Php 将成员设置为绕过_集的替代方法 问题是:
在重载方法中,我将成员设置为相同的实例。将值更改为小写时,该方法将在执行预期行为之前运行两次 问题是: 是否有其他方法可以设置实例的成员,以防止更改键值后筛选器和验证过程运行两次 守则:Php 将成员设置为绕过_集的替代方法 问题是:,php,Php,在重载方法中,我将成员设置为相同的实例。将值更改为小写时,该方法将在执行预期行为之前运行两次 问题是: 是否有其他方法可以设置实例的成员,以防止更改键值后筛选器和验证过程运行两次 守则: 为什么不直接存储在数组属性中,而不是存储在不同的属性中?您还可以使用_get()来抽象访问,这样替换对外部是透明的。@Calimero我以前做过,但实例是可写的,如果没有必要,我不想使用IteratorAggregate接口。为什么?只是一个更干净的界面,所以如果这是解决问题的唯一办法,那也不是最糟糕的。我不是
为什么不直接存储在数组属性中,而不是存储在不同的属性中?您还可以使用_get()来抽象访问,这样替换对外部是透明的。@Calimero我以前做过,但实例是可写的,如果没有必要,我不想使用IteratorAggregate接口。为什么?只是一个更干净的界面,所以如果这是解决问题的唯一办法,那也不是最糟糕的。我不是说这是批评,但如果你采取肮脏的手段(我现在唯一想到的是绕过u set())使它工作的话,拥有一个干净的界面不会有多大帮助。@Calimero同意,但在我看来,使用这种方法有一个用例。该实例作为结构而不是数组使用。实例用途与stdClass相同,只能使用小写键。变量(和属性)名称在PHP中区分大小写,因此将非小写字符串转换为小写将导致不同的属性名称,这就是PHP在您的情况下执行两次_set的原因(一次用于原始名称,第二次用于转换后的名称,如果转换后有任何差异)。您可以通过使用小写名称和非小写名称设置属性来测试它。正如我所知,除了使用嵌入式存储(如数组或stdObject实例)来绕过此问题之外,没有其他解决方案。
class Foo
{
public function __construct(array $structure = array())
{
$this->extend($structure);
}
public function extend(array $structure)
{
foreach ($structure as $key => $value)
$this->$key = $value;
}
public function __set($name, $value)
{
if(is_array($value) && $this->isAssoc($value))
$value = new static($value);
$key = strtolower($name);
$this->$key = $value;
}
protected function isAssoc(array $array)
{
$keys = array_keys($array);
$filtered = array_filter($keys, 'is_string');
$count = count($filtered);
return (bool)$count;
}
}