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

问题描述 投票:0回答:1

我正在使用 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
都会调用 setter 并返回正确的值。

但是我必须使用

$order->getAttributes()
函数,并且它的默认实现不包括虚拟属性。所以我尝试用以下方法重写这个函数:

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

现在

json_encode($order->getAttributes())
包含空的
notes2
字段,但是
$order->notes2
(显然 - 这会导致
notes2
字段变空)没有值,但是
$order->Notes2
有值!

为什么第一个字符的寄存器会发生这种翻转?如何正确声明

getAttributes()
中可用的虚拟字段?

但是下面的代码(而不是覆盖

attributes()

public function getAttributes($names = null, $except = []) {
    return array_merge(['notes2'], parent::getAttributes($names, $except));
}

表现为没有任何内容被覆盖 -

$order->notes2
$order->Notes2
均已计算,并且
notes2
 内没有 
Notes2
(或 
json_encode($order->getAttributes())

php yii2 attributes yii2-model
1个回答
1
投票

这个大小写敏感问题与 PHP 限制/功能有关 - 方法名称不区分大小写,因此方法提供的虚拟属性也不区分大小写 - 如果您定义/调用它为

getnotes2()
getNotes2()
没有区别,所以有无法区分
$order->notes2
$order->Notes2

这对于不使用方法的常规属性(和属性)的工作方式有所不同,并且它们不受此不区分大小写的限制的影响。您没有解释您想要实现的目标,但是常规属性(由

attributes()
定义)和虚拟属性(由 getter 和 setter 提供)是两个独立的东西,您不能将它们混淆 - 如果您在
 中定义属性attributes()
它将存储在内部数组中,并且 getter/setter 将被忽略(因为常规属性优先于虚拟属性)。

在您的例子中,您定义了相同的属性两次:一次作为常规属性(在

attributes()
中),第二次作为虚拟属性(带有 getter 和 setter)。如果您以正确的大小写使用此属性 (
$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
参数并始终返回
notes2
属性。

© www.soinside.com 2019 - 2024. All rights reserved.