如果项目不在数组中,则无法将 ArrayObject::offsetGet() 函数扩展到 return null
Trouble extending ArrayObject::offsetGet() function to return null if item not in array
本来我以为这会是小菜一碟..不适合我..
如果该项目不在 ArrayObject 中,我正在尝试将 offsetGet() 函数扩展为 return null。到目前为止,我似乎无法让它正常工作。
php-v:5.3.29
我做错了什么?下面是我的代码和错误:
我的扩展 ArrayObject class:
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,我不会得到间接修改错误。我现在很困惑。
任何帮助都会很棒。我用谷歌搜索了又搜索,但没有成功。
更新
----------
当尝试用 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 的重载元素在 -- on line --
中无效
简短回答:这是从 ArrayObject
.
重载 offsetGet()
方法的严重副作用
$array['something']['foo'] = 'bar';
作为赋值的一部分,ArrayObject::offsetGet('something')
被调用并且 return 值被期望为 return 一个引用;问题是,尽管定义了 &offsetGet()
,但实际上 return 并不是一个引用。
你真的 returning 是一个临时变量,因此声明断言对该变量所做的任何更改都不会反映在最终数组。
顺便说一句,如果您改为实施 ArrayAccess
,则不会发生这种情况;当然,您也不会获得 ArrayObject
附带的所有方法:(
更新
从 this report 看来,HHVM 表现出正确的行为,而 PHP 7 不会生成任何通知(但在分配期间有错误的行为)。
我能够使 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];
}
}
本来我以为这会是小菜一碟..不适合我..
如果该项目不在 ArrayObject 中,我正在尝试将 offsetGet() 函数扩展为 return null。到目前为止,我似乎无法让它正常工作。
php-v:5.3.29
我做错了什么?下面是我的代码和错误:
我的扩展 ArrayObject class:
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,我不会得到间接修改错误。我现在很困惑。
任何帮助都会很棒。我用谷歌搜索了又搜索,但没有成功。
更新 ----------
当尝试用 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 的重载元素在 -- on line --
中无效简短回答:这是从 ArrayObject
.
offsetGet()
方法的严重副作用
$array['something']['foo'] = 'bar';
作为赋值的一部分,ArrayObject::offsetGet('something')
被调用并且 return 值被期望为 return 一个引用;问题是,尽管定义了 &offsetGet()
,但实际上 return 并不是一个引用。
你真的 returning 是一个临时变量,因此声明断言对该变量所做的任何更改都不会反映在最终数组。
顺便说一句,如果您改为实施 ArrayAccess
,则不会发生这种情况;当然,您也不会获得 ArrayObject
附带的所有方法:(
更新
从 this report 看来,HHVM 表现出正确的行为,而 PHP 7 不会生成任何通知(但在分配期间有错误的行为)。
我能够使 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];
}
}