1

我有一个包含以下信息的实体类:

class A
{
    ...
    private $share_data;
    public function __construct()
    {
        $this->share_data = array(
            'title' => null,
            'text' => null,
            'image' => null,
            'tab_image' => null
        );
    }
    ...
    public function getTabImage()
    {
        return $this->share_data['tab_image'];
    }

当我使用 Symfony 的表单构建器构建表单时,我使用以下代码:

$builder->add('tab_image', 'text', array('required'=>false, 'mapped'=>true, 'label'=>'a.form.tab.image_url'))

因此,当我尝试运行我的代码时,我收到错误通知:未定义索引:tab_image in...

我认为这是因为在我的数据库中,列类型为 json_array(称为 share_data),因此将调用 setShareData。在数据库值中,仅在 json 对象中定义了标题、文本和图像字段。因此,该对象可能被覆盖到没有 tab_image 键的数组中。我试图通过将 setShareData 更改为以下内容来解决此问题:

public function setShareData($shareData)
{
    // merge so that null values are default
    $this->share_data = array_merge($this->share_data, $shareData);

    return $this;
}

希望它会保留在构造函数中设置的 tab_index 键。但我仍然收到未定义的索引错误。有没有办法在未设置 tab_image 键时将其保持为空?

我想解决这个问题,这样我就可以向 array/json 对象添加新键,而不必检查每个 getter 中是否有 isset。显然,新创建的对象获得了 tab_image 键,但我希望它向后兼容。

4

2 回答 2

0

你有一个错字,试试__construct,你错过了 s

于 2013-08-15T11:17:50.277 回答
0

那么你是从数据库中提取这个实​​体吗?

Doctrine 在水合对象时不会调用构造函数。这有点神奇,但属性可以直接设置。事实上,setSharedData 在水合期间也不会被调用。

您可以收听 postLoad 生命周期事件(http://docs.doctrine-project.org/en/latest/reference/events.html

并做类似的事情:

private function getSharedDataTemplate()
{
    return array(
        'title' => null,
        'text' => null,
        'image' => null,
        'tab_image' => null
    );
}
public function __construct()
{
    // For new'ing objects
    $this->share_data = $this->getSharedDataTemplate();
}
/** @PostLoad */
public function doStuffOnPostLoad()
{
    // merge so that null values are default
    $this->share_data = array_merge($this->getSharedDataTemplate(), $this->share_data);
    return $this;
}

您还可以通过设置某种标志并始终检查是否需要合并数据来使其工作。但是生命周期方法会更干净。

于 2013-08-15T13:54:24.170 回答