Faire un objet PHP se comporter comme un tableau?
Question
J'aimerais pouvoir écrire une classe PHP qui se comporte comme un tableau et utilise la syntaxe normale d'un tableau pour obtenir & amp; réglage.
Par exemple (où Foo est une classe PHP que j'ai créée):
$foo = new Foo();
$foo['fooKey'] = 'foo value';
echo $foo['fooKey'];
Je sais que PHP utilise les méthodes magiques _get et _set mais celles-ci ne vous permettent pas d'utiliser la notation de tableau pour accéder aux éléments. Python le gère en surchargeant __getitem__ et __setitem __.
Y at-il un moyen de faire cela en PHP? Si cela fait une différence, j'utilise PHP 5.2.
La solution
Si vous étendez ArrayObject
ou implémentez ArrayAccess
, vous pouvez faire ce que vous voulez.
Autres conseils
Nope, la diffusion aboutit simplement à un tableau PHP normal. Toutes les fonctionnalités de votre classe dérivée de ArrayObject sont perdues. Découvrez ceci:
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";
Comme prévu, l'appel à array_keys () échoue. De plus, is_array ($ blah) renvoie false. Mais si vous modifiez la ligne du constructeur en:
$blah = (array)new CaseInsensitiveArray(array(
alors vous venez d'obtenir un tableau PHP normal (is_array ($ blah) renvoie true et array_keys ($ blah) fonctionne), mais toutes les fonctionnalités de la sous-classe dérivée de ArrayObject sont perdues (dans ce cas, la casse est insensible à la casse). les clés ne fonctionnent plus). Essayez d’exécuter le code ci-dessus dans les deux sens, et vous verrez ce que je veux dire.
PHP devrait soit fournir un tableau natif dans lequel les clés sont sensibles à la casse, soit rendre ArrayObject convertible en tableau sans perdre les fonctionnalités implémentées par la sous-classe, ou simplement faire en sorte que toutes les fonctions de tableau acceptent les occurrences ArrayObject.