Yii2虚拟属性命名-非常奇怪的大写/小写问题?

时间:2018-11-02 11:27:40

标签: yii2 attributes yii2-model

我正在使用Yii2,并且具有虚拟属性notes2(由GUI函数代替数据库属性注释使用):

class Order extends \yii\db\ActiveRecord
{    
    public function getnotes2() {
        return iconv('UTF-16LE', 'UTF-8', $this->notes);
    }

    public function setnotes2($value) {
        $this->notes = iconv('UTF-8', 'UTF-16LE', $value);
    }
}

在这种情况下,以下代码$order->notes2$order->Notes2都将调用设置器并返回正确的值。

但是我必须使用$order->getAttributes()函数,该函数的默认实现不包含虚拟属性。因此,我尝试使用以下方法覆盖此功能:

public function attributes() {
    $attributes = parent::attributes();
    $attributes['notes2'] = 'notes2';
    return $attributes;
} 

现在json_encode($order->getAttributes())包含空的notes2字段,但是$order->notes2(显然-这导致notes2字段为空)没有值,但是{{1} }具有价值!

为什么这样的第一个字符的寄存器发生触发器?如何正确声明$order->Notes2中可用的虚拟字段?

但是以下代码(而不是覆盖getAttributes()

attributes()

因为没有任何内容被覆盖-public function getAttributes($names = null, $except = []) { return array_merge(['notes2'], parent::getAttributes($names, $except)); } $order->notes2均被计算,并且$order->Notes2中没有notes2(或Notes2

1 个答案:

答案 0 :(得分:1)

此区分大小写的问题与PHP的限制/功能有关-方法名称不区分大小写,因此方法提供的虚拟属性也不区分大小写-如果将其定义/调用为getnotes2()或{{ 1}},因此无法区分getNotes2()$order->notes2

这对于不使用方法的常规属性(和属性)的工作方式有所不同,并且它们不影响这种不区分大小写的限制。您没有解释要实现的目标,但是常规属性(由$order->Notes2定义)和虚拟属性(由getter和setter提供)是两个独立的事物,您无法将它们混淆-如果定义属性在attributes()中,它将被存储在内部数组中,而getter / setter将被忽略(因为常规属性优先于虚拟属性)。

在您的情况下,您定义了两次相同的属性:一次是常规属性(在attributes()中),第二次是虚拟属性(使用getter和setter)。如果您以正确的大小写(attributes())使用此属性,则将使用常规属性。如果大小写不正确($order->notes2)将不使用常规属性(因为它区分大小写并且没有$order->Notes2属性),并且将使用虚拟属性(因为它将忽略大小写)作为后备


如果您唯一想做的就是在Notes2中包含notes2,请尝试以这种方式覆盖getAttributes(),而完全不要触摸getAttributes()

attributes()

但这不会忽略public function getAttributes($names = null, $except = []) { return array_merge( ['notes2' => $this->getNotes2()], parent::getAttributes($names, $except) ); } $names参数,并始终返回$except属性。