2015-04-05 170 views
1

编辑:我意识到文本的数量可能会令人生畏。这个问题的本质:
如何以可以设置多维值的方式实现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(它已经实现了ArrayAccessCountableIteratorAggregate)。
将它应用到一类抱着一个数组,结构,它就像这样:

<?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许可下。

回答

3

我不确定这是否有用。我注意到,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) 
+0

嘿,非常感谢!我必须实现getIterator函数,但这很简单(更新了问题)。谢谢! :) – 2015-04-10 16:49:37