如果此属性为数组,则无法设置对象的属性

时间:2018-02-01 04:05:01

标签: php yii2

  

yii advanced 2.0.13

     

@property $ content保留数组(在保存到DB之前,它将在数据库的json中编码。)

     

@property string $ name

所以在ActiveForm中,我输入了content[image]content[anykey]这样的名字,我也没有像name那样的数组属性;我希望在Post之后添加新值,好吧:

echo $model->name; // output: Test
$model->name = 'any new name';
echo $model->name; // any new name

它有效,但

print_r($model->content);
/* output
Array
(
    [title] => bla
    [anykey] => 
    [seo-title] => bla-bla
)*/

$model->content['anykey'] = 'bla-bla-bla'; 
echo $model->content['anykey']; // null output:      

没有。我们无法在数组属性中设置新值,所以我尝试了下一个提示:

$content = $model->content; 
$content['anykey'] = 'bla-bla-bla'; 
$model->content = $content; 
echo $model->content['anykey']; // bla-bla-bla

它有效

有人可以解释,为什么会发生这种情况?

控制器

<?php

namespace backend\controllers;

use Yii;
use common\models\Categories;
use backend\models\CategoriesCRUD;
use yii\web\Controller;
use yii\web\NotFoundHttpException;
use yii\filters\VerbFilter;
use yii\web\UploadedFile;

/**
 * CategoriesController implements the CRUD actions for Categories model.
 */
class CategoriesController extends Controller
{
    /**
     * @inheritdoc
     */
    public function behaviors()
    {
        return [
            'verbs' => [
                'class' => VerbFilter::className(),
                'actions' => [
                    'delete' => ['POST'],
                ],
            ],
        ];
    }
    ...

    /**
     * Updates an existing Categories model.
     * If update is successful, the browser will be redirected to the 'view' page.
     * @param integer $id
     * @return mixed
     */
    public function actionUpdate($id)
    {
        $model = $this->findModel($id);

        // here I put code above
        $model->content['anykey'] = 'bla-bla-bla'; 
        echo $model->content['anykey']; // old value
        // die();
        if ($model->load(Yii::$app->request->post()) && $model->save()) {
            return $this->redirect(['view', 'id' => $model->id]);
        } else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    }
}

模型

<?php

namespace common\models;

use Yii;
use yii\web\UploadedFile;

/**
 * This is the model class for table "{{%categories}}".
 *
 * @property integer $id
 * @property string $name
 * @property integer $status
 * @property integer $sort_order
 * @property integer $parent_id
 * @property string $content
 *
 * @property Categories $parent
 * @property Categories[] $categories
 * @property CategoriesRelationships[] $categoriesRelationships
 * @property CategoriesRelationships[] $categoriesRelationships0
 * @property ProductsToCategories[] $productsToCategories
 */
class Categories extends \yii\db\ActiveRecord
{

    /**
     * @inheritdoc
     */
    public static function tableName()
    {
        return '{{%categories}}';
    }

    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            [['name'], 'required'],
            [['status', 'sort_order'], 'integer'],
            ['content', 'each', 'rule' => ['trim']],
            [['name'], 'string', 'max' => 255],
            [['parent_id'], 'exist', 'skipOnError' => true, 'targetClass' => Categories::className(), 'targetAttribute' => ['parent_id' => 'id']],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'id' => 'ID',
            'name' => 'Заголовок',
            'status' => 'Показывать',
            'sort_order' => 'Порядок сортировки',
            'parent_id' => 'Родительская категория',
            'content' => 'Содержание',
        ];
    }

    public function beforeSave($insert)
    {
        if (parent::beforeSave($insert)) {
            /* Обработка данных перед занесением в базу
                в content содержится любая контентная информация
            */
            // @TODO добавить собственную валидацию изображений и свои методы для их обработки (Для категорий, аватарок и прч)

            // here I put solution, but before I found it I've been trying in Controller
            $content = (array) $this->content;
            $content['image'] = $this->uploadImage($this, $content, 'image', 'content[image]');
            $this->content = $content;


            $this->content = json_encode($this->content, JSON_UNESCAPED_UNICODE);

            return true;
        }
        return false;
    }
}

1 个答案:

答案 0 :(得分:0)

虽然这不是你问题的直接答案:

我建议对序列化值使用不同的属性,比如serializedContent。这样 - content始终是一个数组,serializedContent总是一个json字符串。

然后在模型中创建一个setter和一个getter:

public function setContent($value) {
    $this->serializedContent = json_encode($value);
}


public function getContent() {
    return json_decode($this->serializedContent,true);
}