Fazer um PHP objeto de comportar-se como um array?
Pergunta
Eu gostaria de ser capaz de escrever uma classe PHP que se comporta como uma matriz e usa matriz normal sintaxe para pegar e definição.
Por exemplo (onde Foo é uma classe PHP de minha criação):
$foo = new Foo();
$foo['fooKey'] = 'foo value';
echo $foo['fooKey'];
Eu sei que o PHP tem a _get e _set magia métodos, mas aqueles que não permitem que você use a notação de matriz para ter acesso aos itens.Python lida com ele por sobrecarga __getitem__ e __setitem__.
Existe uma maneira de fazer isso em PHP?Se ele faz a diferença, eu estou rodando o PHP 5.2.
Solução
Se você estender ArrayObject
ou implementar ArrayAccess
em seguida, você pode fazer o que quiser.
Outras dicas
Nope, lançando-se apenas os resultados normais em um matriz PHP -- perder qualquer funcionalidade que o seu ArrayObject classe derivada tinha.Confira:
class CaseInsensitiveArray extends ArrayObject {
public function __construct($input = array(), $flags = 0, $iterator_class = 'ArrayIterator') {
if (isset($input) && is_array($input)) {
$tmpargs = func_get_args();
$tmpargs[0] = array_change_key_case($tmpargs[0], CASE_LOWER);
return call_user_func_array(array('parent', __FUNCTION__), $tmp args);
}
return call_user_func_array(array('parent', __FUNCTION__), func_get_args());
}
public function offsetExists($index) {
if (is_string($index)) return parent::offsetExists(strtolower($index));
return parent::offsetExists($index);
}
public function offsetGet($index) {
if (is_string($index)) return parent::offsetGet(strtolower($index));
return parent::offsetGet($index);
}
public function offsetSet($index, $value) {
if (is_string($index)) return parent::offsetSet(strtolower($index, $value));
return parent::offsetSet($index, $value);
}
public function offsetUnset($index) {
if (is_string($index)) return parent::offsetUnset(strtolower($index));
return parent::offsetUnset($index);
}
}
$blah = new CaseInsensitiveArray(array(
'A'=>'hello',
'bcD'=>'goodbye',
'efg'=>'Aloha',
));
echo "is array: ".is_array($blah)."\n";
print_r($blah);
print_r(array_keys($blah));
echo $blah['a']."\n";
echo $blah['BCD']."\n";
echo $blah['eFg']."\n";
echo $blah['A']."\n";
Como esperado, o array_keys() falha de chamada.Além disso, is_array($blá) retorna false.Mas, se você alterar o construtor de linha para:
$blah = (array)new CaseInsensitiveArray(array(
em seguida, você acabou de obter um normal PHP matriz (is_array($blá) devolve verdadeiro, e array_keys($blá) funciona), mas a todas as funcionalidades do ArrayObject derivada de subclasse é perdido (neste caso, não diferencia maiúsculas de minúsculas teclas deixaram de funcionar).Tente executar o código acima em ambos os sentidos, e você verá o que quero dizer.
O PHP deve fornecer um nativo matriz em que as chaves são case-insensitive, ou fazer ArrayObject ser concreto para a matriz sem perder qualquer funcionalidade que a subclasse implementa, ou simplesmente fazer todas as funções de matriz aceitar ArrayObject instâncias.