Utiliser l'écriture Array sous forme Object en PHP (POO, ArrayAccess)

Publié le 25 août 2008 par Mr32

Comme annoncé la semaine dernière et les vacances se terminant, il est maintenant temps de remonter (un peu) le niveau de ce blog qui sombrait doucement mais sûrement dans le grand n'importe quoi.

L'astuce du jour n'est guère facile à expliquer en quelques lignes, un exemple sera à mon avis beaucoup plus clair.
Comment utiliser un tableau comme un pur objet ? ( à la sauce Java, si je puis m'exprimer ainsi )

// Ecriture PHP classique
$array = array(); // Ligne facultative
$array['key1'] = 'value 1';
$array['key2'] = 'value 2';
$array['key3']['key31'] = 'value 31';
...

Voici une écriture qui ne fonctionne qu'en PHP 5 :

// Ecriture PHP5 objet
$array = new ClassArray(); // Ligne obligatoire !
$array['key1'] = 'value 1';
$array['key2'] = 'value 2';
...

En soit, il n'y a absolument rien de révolutionnaire, mais le new crée l'instance de l'objet ClassArray() et vous pouvez constater que l'écriture reste un tableau et non un objet
$array->key1 = 'value 1';

Une question se pose sûrement dans votre cerveau qui bouillonne d'impatience : Qui a-t-il dans cette ClassArray() ? Une simple implémentation de ArrayAccess ( PHP5 only ), ce qui nous donne :

class ClassArray implements ArrayAccess {
	
	protected $_array = array();
	
	public function __construct() {
		$this->_array = func_get_args();
	}
	
	// En cas d'appel de la fonction isset()
	public function offsetExists($offset) {
		return isset($this->_array[$offset]);
	}
	
	// En cas d'appel de la valeur
	public function offsetGet($offset) {
		return $this->_array[$offset];
	}
	
	// En cas d'affectation de la valeur
	public function offsetSet($offset, $value) {
		return $this->_array[$offset] = $value;
	}
	
	// En cas d'appel de la fonction unset()
	public function offsetUnset($offset) {
		unset($this->_array[$offset]);
	}
	
}

Ensuite, libre à vous de modifier cette classe pour lui ajouter de nouvelles fonctionnalités...

Remarque importante : Si vous essayez de créer un tableau sur plusieurs dimensions, un message d'erreur se produira avec l'écriture suivante :

$array = new ClassArray();
$array['key3']['key31'] = 'value 31';

// Problème : Vous n'avez pas définit $array['key3'] ! l'écriture POO est beaucoup plus stricte ;)
// Solution :
$array = new ClassArray();
$array['key3'] = new ClassArray();
$array['key3']['key31'] = 'value 31';

Documentation officielle :
http://www.php.net/~helly/php/ext/spl/interfaceArrayAccess.html