Php 未在ArrayObject中调用偏移集
php代码示例:Php 未在ArrayObject中调用偏移集,php,arrayobject,Php,Arrayobject,php代码示例: class TestArrayObject extends ArrayObject { function offsetSet($index,$val){ echo $index.':'.$val.PHP_EOL; } } $s = new TestArrayObject(); //test 1 $s['a'] = 'value';//calls offsetSet //test 2 $s['b']['c'] = 'value';//does
class TestArrayObject extends ArrayObject {
function offsetSet($index,$val){
echo $index.':'.$val.PHP_EOL;
}
}
$s = new TestArrayObject();
//test 1
$s['a'] = 'value';//calls offsetSet
//test 2
$s['b']['c'] = 'value';//does not call offsetSet, why?
var_dump($s);
为什么Test2不调用offsetSet方法?
ArrayObject
是一个很大的魔法,因此我不建议使用它,或者更糟糕的是,扩展它
但是您的实际问题与ArrayObject
本身无关。您遇到的是$s['b']['c']=
是所谓的对'b'
偏移量的间接修改。PHP为其执行的代码大致如下所示:
$offset =& $s['b'];
$offset['c'] = ...;
正如您所看到的,偏移量
'b'
从未直接写入。相反,它是通过引用获取的,并且引用被修改。这就是为什么会调用offsetGet
,而不是offsetSet
对于多维数组,请参见用户提供的注释这是一种“陷阱”,因为我认为预期行为将与问题中的OP一样
此外,当作为对象或数组访问ArrayObject时,行为不一致
例如:
$foo['b']['c'] = 'value'; // no warning
var_dump($foo);
$bar->b->c = 'value'; // triggers warning
var_dump($bar);
我自己的类在扩展ArrayObject时遇到了同样的问题。我无法解决这个问题,但通过实现一个新方法来解决它,我使用这个方法来链接属性创建
class Arraylist extends ArrayObject
{
public function set($key, $value = null)
{
if (!is_null($value)) {
$val = new ArrayList((array) $value);
} else {
$val = new ArrayList();
}
$this->offsetSet($key, $val);
return $this->offsetGet($key);
}
public function offsetSet($index,$val){
echo $index.':'.$val.PHP_EOL;
parent::offsetSet($index, $val);
}
}
使用OPs示例:
代码:
产出:
0:value
a:ArrayList
0:value
b:ArrayList
0:another value
c:ArrayList
0:another value
class ArrayList#5 (2) {
public $a =>
class ArrayList#7 (1) {
string(5) "value"
}
public $b =>
class ArrayList#8 (1) {
public $c =>
class ArrayList#9 (1) {
string(13) "another value"
}
}
}
这无法修复间接呼叫。感谢您分享您的经验!
0:value
a:ArrayList
0:value
b:ArrayList
0:another value
c:ArrayList
0:another value
class ArrayList#5 (2) {
public $a =>
class ArrayList#7 (1) {
string(5) "value"
}
public $b =>
class ArrayList#8 (1) {
public $c =>
class ArrayList#9 (1) {
string(13) "another value"
}
}
}