Fare in modo che un oggetto PHP si comporti come un array?
Domanda
Mi piacerebbe essere in grado di scrivere una classe PHP che si comporti come un array e utilizzi la normale sintassi dell'array per ottenere e impostare.
Ad esempio (dove Foo è una classe PHP di mia creazione):
$foo = new Foo();
$foo['fooKey'] = 'foo value';
echo $foo['fooKey'];
So che PHP ha i metodi magici _get e _set, ma questi non ti consentono di utilizzare la notazione di array per accedere agli elementi.Python lo gestisce sovraccaricando __getitem__ e __setitem__.
C'è un modo per farlo in PHP?Se fa la differenza, sto utilizzando PHP 5.2.
Soluzione
Se estendi ArrayObject
o implementare ArrayAccess
poi puoi fare quello che vuoi.
Altri suggerimenti
No, il casting si traduce semplicemente in un normale array PHP: perde qualsiasi funzionalità posseduta dalla classe derivata da ArrayObject.Controllalo:
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";
Come previsto, la chiamata array_keys() fallisce.Inoltre, is_array($blah) restituisce false.Ma se cambi la riga del costruttore in:
$blah = (array)new CaseInsensitiveArray(array(
quindi ottieni semplicemente un normale array PHP (is_array($blah) restituisce true e array_keys($blah) funziona), ma tutta la funzionalità della sottoclasse derivata da ArrayObject viene persa (in questo caso, le chiavi senza distinzione tra maiuscole e minuscole non sono più lavoro).Prova a eseguire il codice sopra in entrambi i modi e vedrai cosa intendo.
PHP dovrebbe fornire un array nativo in cui le chiavi non fanno distinzione tra maiuscole e minuscole, oppure rendere ArrayObject trasformabile in array senza perdere le funzionalità implementate dalla sottoclasse, o semplicemente fare in modo che tutte le funzioni dell'array accettino istanze di ArrayObject.