Revisando la clase ArrayCollection de Doctrine – Parte 1

Cuando trabajamos con Doctrine y con relaciones entre las Entities aparece la clase ArrayCollection, esta clase es un wrapper de un array PHP que añade cierta funcionalidad. Normalmente se usa como un array normal, pero ArrayCollection dispone de otros métodos que lo hacen interesante, vamos a hacer un repaso a algunos de esos métodos con ejemplos y en la siguiente parte nos centraremos en el método matching que nos permitirá hacer queries sobre el propio ArrayCollection. Este artículo será un poco largo, pero muy ameno de leer ya que contiene mucho código.

Vamos primero a configurar el entorno como ya vimos, el composer.json que usaremos será el siguiente:

Creamos dos sencillos modelos para hacer las pruebas, Person:

Y Grade:

Y finalmente un fichero playgroundArrayCollection.php donde probaremos la clase ArrayCollection en el directorio raíz del proyecto, de forma que el proyecto quedaría así:

Añadimos al fichero playgroundArrayCollection.php las líneas para cargar las clases y añadimos unos datos de prueba que será con los que trabajaremos:

Ya lo tenemos todo listo, vamos a repasar los métodos de ArrayCollection y veremos un ejemplo con cada uno, estos métodos vienen dados por la interfaz Doctrine\Common\Collections\Collection.

Closure

Los siguientes ejemplos hacen uso de objetos Closure, por lo que se recomienda saber cómo funcionan este tipo de objetos para entender mejor el código. Un ejemplo sencillo sacado de la documentación de PHP:

Dando un paso más y aunque no tenga mucho sentido (pero sí tiene para entender los posteriores ejemplos) si quisiéramos añadir una despedida dado el mismo saludo, se podría hacer de la siguiente forma:

Cuando ejecutamos $greet(‘World’) nos devuelve otro objeto Closure que espera el parámetro de despedida.

Una vez visto por por encima los objetos Closure, pasamos a los métodos de ArrayCollection:

Exists

Este método recibe un objeto Closure y comprueba que existe al menos un elemento que cumple con la closure que le pasamos y en cuyo caso devuelve TRUE, si no lo cumple ninguno devuelve FALSE.

En nuestro ejemplo vamos a comprobar si hay alguna persona que se llame Penny y si hay alguna que se llame Andrew:

ForAll

Este método recibe un objeto Closure y comprueba que todos los elementos cumplen con la closure que le pasamos y en cuyo caso devuelve TRUE, si hay alguno que no lo cumple devuelve FALSE.

En este caso vamos a comprobar si todos han aprobado Maths y si todos han aprobado Gym:

Map

Este método recibe un objeto Closure y devuelve una nueva colección resultante de aplicar la closure a todos los elementos, internamente llama a array_map.

Vamos a subirle un 2.5 puntos la nota en Maths a todos:

Filter

Este método recibe un objeto Closure y devuelve una nueva colección resultante de aplicar la closure a todos los elementos y quedarse con los que cumplen la closure, internamente llama a array_filter.

Vamos a filtrar las personas que tienen la asignatura de Physics y las que tienen Chemistry:

Partition

Este método recibe un objeto Closure y devuelve dos ArrayCollections según si cumplen o no la closure, la diferencia con filter es que en este caso devuelve tanto los que cumplen la closure como los que no.

Vamos a dividir la gente entre los que han aprobado todas las asignaturas de los que no:

Hasta aquí los métodos que veremos en este artículo, en el siguiente veremos exclusivamente el método matching.