Conjunto de ArrayAccess PHP multidimensional

EDIT: percebi que a quantidade de texto pode ser intimidante. A essência desta questão:
Como implementar o ArrayAccess de forma a tornar possíveis valores multidimensionais?


Estou ciente de que isso já foi discutido aqui, mas parece incapaz de implementar a interface ArrayAccess corretamente.

Basicamente, eu tenho uma class para lidar com a configuração do aplicativo com uma matriz e implementou o ArrayAccess . A recuperação de valores funciona bem, mesmo valores de chaves aninhadas ( $port = $config['app']['port']; ). Definir valores funciona apenas para arrays unidimensionais, no entanto: Assim que eu tentar (não) definir um valor (por exemplo, a porta no exemplo anterior), recebo a seguinte mensagem de erro:

 Notice: Indirect modification of overloaded element  has no effect in  on  

Agora, a opinião geral parece ser que o método offsetGet() deve retornar por referência ( &offsetGet() ). Isso, no entanto, não resolve o problema e tenho medo de não saber como implementar esse método corretamente – por que um método getter é usado para definir um valor? O documento php aqui também não é útil.

Para replicar diretamente isso (PHP 5.4-5.6), encontre um exemplo de código anexado abaixo:

 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'; 

EDITAR 2: a solução, como Ryan apontou, era usar ArrayObject em vez disso (o que já implementa ArrayAccess , ArrayAccess e IteratorAggregate ).
Para aplicá-lo a uma class que contém uma matriz, estrutura-a assim:

 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); } } 

Eu usei isso para minha biblioteca Config libconfig que está disponível no Github sob a licença MIT.

Não tenho certeza se isso será útil. Tenho notado que a class ArrayObject é “interessante” …

Não tenho a certeza de que esta seja até uma “resposta”. É mais uma observação sobre esta class.

Ele lida as coisas da “multidimensional array” corretamente como padrão.

Você pode adicionar methods para fazê-lo fazer mais do que você deseja?

  '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']); 

Saída:

 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) 
Intereting Posts