最初我以为这将是一块蛋糕..不适合我......
我试图扩展offsetGet()函数,如果该项不在ArrayObject中,则返回null。到目前为止,我似乎无法正常工作。
php -v:5.3.29
我做错了什么?下面是我的代码和错误:
我的扩展ArrayObject类:
class IssetArray extends \ArrayObject {
public function &offsetGet($offset) {
$var = $this->offsetExists($offset) ? parent::offsetGet($offset) : null;
return $var;
}
}
以下是我的称呼方式:
$array = new \IssetArray();
$array['item'] = 123;
var_dump($array['item']);
var_dump($array['something']['noItem']);
$array['something']['foo'] = 'bar';
var_dump($array['something']['foo']);
$normalArrayObject = new \ArrayObject();
$normalArrayObject['something']['foo'] = 'bar';
var_dump($normalArrayObject['something']['foo']);
var_dump($normalArrayObject['something']['noItem']);
输出:
int(123)
NULL
Notice: Indirect modification of overloaded element of \IssetArray has no effect in -- on line --
NULL
string(3) "bar"
Notice: Undefined index: noItem in -- on line --
NULL
我做错了什么?如果我调用普通的ArrayObject,我不会得到间接修改错误。我在这一点上很困惑。
任何帮助都会很精彩。我用Google搜索并用Google搜索,没有运气。
更新 -----------
当尝试使用ArrayAccess执行相同操作时,我遇到了同样的问题。我如何使用ArrayAccess来解决这个问题?
我的实施:
class IssetArray implements \ArrayAccess {
private $container = array();
public function __construct() {}
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetExists($offset) {
return isset($this->container[$offset]);
}
public function offsetUnset($offset) {
unset($this->container[$offset]);
}
public function &offsetGet($offset) {
$var = isset($this->container[$offset]) ? $this->container[$offset] : null;
return $var;
}
}
这导致了我在ArrayObject中遇到的相同问题。注意:间接修改\ IssetArray的重载元素对 - 在线 -
没有影响答案 0 :(得分:2)
简短回答:这是从offsetGet()
重载ArrayObject
方法的一个令人讨厌的副作用。
$array['something']['foo'] = 'bar';
作为赋值的一部分,调用ArrayObject::offsetGet('something')
并且返回值应返回引用;问题在于,尽管有&offsetGet()
的定义,但它实际上并没有返回引用。
你真正返回的是一个临时变量,因此通知是正确的,断言对该变量所做的任何更改都不会反映在最终数组中。
顺便说一句,如果你实施ArrayAccess
,这不会发生;当然,你不会得到ArrayObject
附带的所有方法:(
从this report看来,HHVM表现出正确的行为,PHP 7不会生成任何通知(但在分配期间行为错误)。
答案 1 :(得分:1)
我能够使下面的ArrayAccess实现完美地满足我的需求。我希望这可以帮助那些遇到类似问题的人。
感谢@Jack帮助我朝着正确的方向前进!
class IssetArray implements \ArrayAccess {
private $container = array();
public function __construct() {}
public function offsetSet($offset, $value) {
if (is_null($offset)) {
$this->container[] = $value;
} else {
$this->container[$offset] = $value;
}
}
public function offsetExists($offset) {
return isset($this->container[$offset]);
}
public function offsetUnset($offset) {
unset($this->container[$offset]);
}
public function &offsetGet($offset) {
if(!isset($this->container[$offset])) {
$this->container[$offset] = null;
}
return $this->container[$offset];
}
}