On peux surcharger la méthode count. C’est d’ailleurs le cas dans le cas du Paginator de doctrine.
123456789
$dql="SELECT p, c FROM BlogPost p JOIN p.comments c";$query=$entityManager->createQuery($dql)->setFirstResult(0)->setMaxResults(10);$paginator=newPaginator($query);count($paginator)// nombre de lignes dans la base
Les ArrayObjects
On peut aussi changer toutes les méthodes pour un tableau.
classGeekCounterimplementsCountable,ArrayAccess{publicfunctioncount(){return42;}publicfunctionoffsetSet($offset,$value){if(is_null($offset)){echo("on ajoute $value\n");}else{echo("on change la clé $offset par $value\n");}}publicfunctionoffsetExists($offset){echo("on teste la clé $offset\n");returntrue;}publicfunctionoffsetUnset($offset){echo("on unset la clé $offset\n");}publicfunctionoffsetGet($offset){echo("on me demande la clé $offset\n");return42;}}$counter=newGeekCounter();var_dump(isset($counter["IdontCare"]));var_dump($counter["IdontCare"]);unset($counter["IdontCare"]);$counter[]=3;$counter["IdontCare"]=3;
On trouve la même idée dans les collections de doctrine.(l’interface Collection n’est qu’une surcharge);
Si on ne souhaite pas tout implémenter il suffit de surcharger la Classe ArrayObject
Par exemple:
12345678910
classZooDeBeauvalextendsArrayObject{publicfunctionoffsetSet($offset,$value){if(!in_array($value,array("Panda","Koala","Otarie"))){echo"non cet animal $value n'est pas autorisé";}else{parent::offsetSet($offset,$value);}}}
Pour les foreach j’ai déjà parlé des iterators et des générateurs.
Conclusion
Maintenant les interfaces ArrayAccess et Countable n’ont plus de secrets pour vous. Nous verrons dans un prochain Post les listes chainées. L’avantage de ces méthode est que l’on obtient une structure qui se comporte comme un array mais avec une occupation mémoire moindre.
Dans un prochain post, je vais parler des listes chainées et des différentes structure de la SPL (j’ai déja parlé de la SplStack)