PHP ArrayAccess set multidimensional
问题描述:
编辑:我意识到文本的数量可能会令人生畏。这个问题的本质:
如何以可以设置多维值的方式实现ArrayAccess?PHP ArrayAccess set multidimensional
我知道,这是讨论here已经但是我似乎无法正确实现了ArrayAccess接口。
基本上,我有一个类来处理与阵列的应用程序配置,并实施ArrayAccess
。检索值可以正常工作,甚至可以嵌套键值($port = $config['app']['port'];
)。设定值仅适用于一维数组,虽然:当我尝试(UN)设定的值(如前面例子中的端口),我收到以下错误信息:
Notice: Indirect modification of overloaded element <object name> has no effect in <file> on <line>
现在一般意见似乎是offsetGet()
方法必须通过参考返回(&offsetGet()
)。但是,这并不能解决问题,我害怕我不知道如何正确实现该方法 - 为什么使用getter方法来设置值? php文档here也不是真的有用。
要直接复制本(PHP 5.4-5.6),请看下面附接一个示例代码:
<?php
class Config implements \ArrayAccess
{
private $data = array();
public function __construct($data)
{
$this->data = $data;
}
/**
* ArrayAccess Interface
*
*/
public function offsetSet($offset, $value)
{
if (is_null($offset)) {
$this->data[] = $value;
} else {
$this->data[$offset] = $value;
}
}
public function &offsetGet($offset)
{
return isset($this->data[$offset]) ? $this->data[$offset] : null;
}
public function offsetExists($offset)
{
return isset($this->data[$offset]);
}
public function offsetUnset($offset)
{
unset($this->data[$offset]);
}
}
$conf = new Config(array('a' => 'foo', 'b' => 'bar', 'c' => array('sub' => 'baz')));
$conf['c']['sub'] = 'notbaz';
编辑2:将溶液,正如Ryan所指出的那样,是使用ArrayObject(它已经实现了ArrayAccess
,Countable
和IteratorAggregate
)。
将它应用到一类抱着一个数组,结构,它就像这样:
<?php
class Config extends \ArrayObject
{
private $data = array();
public function __construct($data)
{
$this->data = $data;
parent::__construct($this->data);
}
/**
* Iterator Interface
*
*/
public function getIterator() {
return new \ArrayIterator($this->data);
}
/**
* Count Interface
*
*/
public function count()
{
return count($this->data);
}
}
我用这对我的配置库libconfig
,您可在Github在MIT许可下。
答
我不确定这是否有用。我注意到,ArrayObject
类是'有趣的'...
我不确定这是甚至'答案'。这更多是关于这堂课的观察。
它按照标准正确处理'多维数组'。
您可以添加方法使其更加符合您的需求?
<?php //
class Config extends \ArrayObject
{
// private $data = array();
public function __construct(array $data = array())
{
parent::__construct($data);
}
}
$conf = new Config(array('a' => 'foo', 'b' => 'bar', 'c' => array('sub' => 'baz')));
$conf['c']['sub'] = 'notbaz';
$conf['c']['sub2'] = 'notbaz2';
var_dump($conf, $conf['c'], $conf['c']['sub']);
unset($conf['c']['sub']);
var_dump('isset?: ', isset($conf['c']['sub']));
var_dump($conf, $conf['c'], $conf['c']['sub2']);
输出:
object(Config)[1]
public 'a' => string 'foo' (length=3)
public 'b' => string 'bar' (length=3)
public 'c' =>
array
'sub' => string 'notbaz' (length=6)
'sub2' => string 'notbaz2' (length=7)
array
'sub' => string 'notbaz' (length=6)
'sub2' => string 'notbaz2' (length=7)
string 'notbaz' (length=6)
string 'isset?: ' (length=8)
boolean false
object(Config)[1]
public 'a' => string 'foo' (length=3)
public 'b' => string 'bar' (length=3)
public 'c' =>
array
'sub2' => string 'notbaz2' (length=7)
array
'sub2' => string 'notbaz2' (length=7)
string 'notbaz2' (length=7)
嘿,非常感谢!我必须实现getIterator函数,但这很简单(更新了问题)。谢谢! :) – 2015-04-10 16:49:37