¿Qué son los traits en PHP?

Descubre qué son los traits de PHP y cómo puedes emplearlos para reutilizar código

Image for post
Image for post

Con la versión 5.4 de PHP (ha llovido ya un poco) apareció una nueva característica conocida como traits que permitía reutilizar código entre distintas clases sin recurrir a la herencia. He decidido crear este artículo porque creo que los traits es de esas características que si no has profundizado mucho en el lenguaje pasan desapercibidas hasta que un día ves dentro de una clase algo de este estilo:

y te preguntas por qué está declarando ahí un use en vez de hacerlo al comienzo del archivo donde habitualmente estamos acostumbrados.

Así que en este artículo realizaré una introducción a los traits en PHP y sus posibles usos. ¡Espero que os sirva el artículo!

Una breve introducción

Como sabréis, en PHP una clase únicamente puede heredar de otra a diferencia de otros lenguajes como C++ en el que se permite la herencia múltiple:

Si bien podríamos discutir hasta qué punto recurrir a la herencia múltiple es o no una buena práctica, es innegable que en ciertas ocasiones nos puede ayudar a seguir el principio DRY (don’t repeat yourself). Es aquí donde el concepto de los traits nos puede ser útil, permitiéndonos reutilizar código entre distintas clases pese a no disponer de herencia múltiple. Veamos cómo funcionan.

¿Cómo funcionan los traits en PHP?

Como decía al principio del artículo, los traits fueron introducidos en la versión 5.4 de PHP. Son muy similares a una clase (pero que no podemos instanciar) y su objetivo es agrupar funcionalidad muy específica y de manera coherente. Por ejemplo:

Una vez declarado un trait, podemos reutilizarlo tantas veces como queramos de la siguiente forma:

De este modo, tanto la clase A como la clase B obtendrían la propiedad createdAt así como sus métodos getter y setter declarados en el trait. Fácil, ¿verdad?

Características de los traits

Entre las principales características de los traits se encuentran las siguientes:

Pueden definir métodos y propiedades con cualquier nivel de acceso tal y como hemos visto en el ejemplo anterior.

Pueden definir constructores y destructores, por ejemplo:

Pueden definir métodos abstractos que fuercen a las clases que emplean el trait a implementarlos:

Pueden también definir propiedades y métodos estáticos:

Una clase puede emplear tantos traits como quiera:

Los traits además pueden componerse con otros:

Precedencia en los traits

Como regla general los miembros de la clase que emplea el trait sobrescriben los miembros definidos en el trait que a su vez (y esto es importante) sobrescribe los heredados. Es decir:

Es decir, el método doFoo de la clase Foo es sobrescrito por el trait Bar . Sin embargo:

La clase que usa el trait sobrescribe los métodos definidos en el trait.

En el caso de que dos traits definan el mismo método se producirá un error fatal salvo que resolvamos explícitamente el conflicto mediante la instrucción insteadof del siguiente modo:

Conclusiones

Como veis, los traits nos dan una gran flexibilidad a la hora de reutilizar código sin tener que recurrir a la herencia múltiple, pues con ellos podemos encapsular una cierta funcionalidad (como por ejemplo la característica de posee un atributo createdAt en la clase) y reusarla siempre que queramos. De hecho, si trabajáis con las DoctrineExtensions de Gedmo es probable que ya os suenen algunas de las que se definen en esta librería, por lo que su uso no es algo tan residual como cabría pensar.

Sin embargo, antes de precipitarnos a crear una trait, mi recomendación es que primero penséis si no existe algún patrón de diseño en PHP que encaje más con el resultado que buscáis. Por ejemplo, recordad que para añadir funcionalidad a una clase sin recurrir a la herencia también existe el patrón Decorador (el cual “funciona” mediante composición respetando el principio Open-Closed) y que además es posible implementar directamente en el container de Symfony:

https://medium.com/@ger86/c%C3%B3mo-decorar-nuestros-repositorios-en-symfony-2353960ba125

¿Quieres recibir más artículos como este?

Suscríbete a nuestra newsletter:

Written by

Entre paseo y paseo con Simba desarrollo en Symfony y React

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store