我正在使用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
)>
答案 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
属性。