Qué es el trait Macroable
El traitMacroable es un mecanismo que permite añadir métodos dinámicamente a una clase después de haberla escrito, sin modificarla. Muchas clases del core de Laravel lo utilizan, así que puedes extender sus funcionalidades sin tocar el código del framework.
La implementación real del trait está en Illuminate\Support\Traits\Macroable. Internamente guarda las macros registradas en una propiedad estática $macros y las invoca a través de los métodos mágicos __call / __callStatic.
Clases que usan Macroable
Laravel tiene muchas clases compatibles con Macroable.macro() — añadir un método
Almacro() le pasas el nombre del método como primer argumento y un closure como segundo.
$this dentro del closure queda vinculado a la instancia que invocó la macro. Así puedes acceder directamente a las propiedades y métodos de la clase.
mixin() — añadir varios métodos a la vez
Para registrar muchas macros en bloque, usamixin(). Todos los métodos public / protected de la clase mixin se registran como macros.
Los métodos del
mixin() deben devolver el closure que se registrará como macro. El valor devuelto por el método es la implementación real de la macro.Registro en un service provider
Las macros deben registrarse durante el arranque de la aplicación. El sitio adecuado es el métodoboot() de AppServiceProvider.
Casos de uso prácticos
Extensión de Collection
Añadir métodos personalizados a las colecciones es el caso más habitual.Extensión de la clase Str
Extensión de la clase Request
Extensión de Blueprint (migraciones)
Al convertir en macros las definiciones de columnas del esquema, mantienes un diseño de BD consistente.Extensión de TestResponse
Puedes añadir métodos de assertion específicos para tests.hasMacro() — comprobar si existe una macro
flushMacros() — resetear las macros
Se usa cuando quieres resetear las macros en un test.Macros estáticas
Las macros funcionan también como métodos estáticos, no solo como métodos de instancia. Las gestiona__callStatic.
Usar Macroable en tus propias clases
Puedes incorporarMacroable también a tus propias clases.
Detalles de la implementación interna
Closure::bindTo(). Así, dentro de la macro, $this apunta al objeto que la invocó. Si el macro no es un closure (por ejemplo, un objeto invokable), no se realiza el bind.
Próximos pasos
Patrón Pipeline
Aprende cómo componer varios pasos de procesamiento en serie usando el patrón Pipeline.