Skip to main content
Un paquete Laravel no acaba con su primer release. Para mantenerlo durante años acompañando las actualizaciones del propio Laravel, PHP y sus dependencias, necesitas ejecutar de forma continua no solo los tests, sino también el análisis estático.
Esta página complementa Desarrollo de paquetes Laravel, Probar paquetes Laravel con Orchestra Testbench y Gestión de la compatibilidad de versiones de paquetes. Añadir análisis estático a tu estrategia de implementación, tests y versiones te dará un paquete mucho más fácil de mantener a largo plazo.

Qué es el análisis estático

El análisis estático detecta incoherencias de tipos y bugs potenciales sin ejecutar el código. En los paquetes Laravel, con tantos mecanismos dinámicos (contenedor de servicios, facades, Eloquent), permite capturar problemas antes de que aparezcan en tiempo de ejecución. Introducir análisis estático aporta principalmente estos beneficios:
  • Mayor seguridad de tipos — detectas argumentos y retornos incorrectos antes de la review.
  • Detección temprana de bugs — llamadas a métodos inexistentes o nullables olvidados salen antes de los tests.
  • Mejor autocompletado del IDE — ajustar PHPDoc y generics eleva la precisión.
  • Mantenimiento estable a largo plazo — es más fácil identificar qué se rompe al actualizar Laravel o PHP.

Configuración de PHPStan

Empieza montando la base de análisis con PHPStan solo. PHPStan 2.x es más estricto con mixed y los nullables que antes, lo que también es una buena excusa para pulir la API pública de tu paquete.
1

Añade PHPStan como dependencia de desarrollo

2

Primero, analiza directamente los directorios objetivo

En los paquetes suele empezarse con src y tests.
3

Fíjalo en un script de Composer

Para usar el mismo comando en CI y en local, define un script en composer.json.

Configuración de Larastan

Con solo PHPStan, en un paquete Laravel no capturas del todo mecanismos específicos como la resolución vía contenedor, los facades o las relaciones de Eloquent. Por eso se combina con Larastan, la extensión de PHPStan para Laravel.
1

Añade Larastan

Su nombre actual es larastan/larastan. En artículos antiguos verás nunomaduro/larastan.
2

Si desarrollas un paquete, instala también Testbench

Larastan arranca el contenedor de aplicación de Laravel para resolver tipos. Cuando analizas un paquete Laravel aislado, puede que necesites orchestra/testbench.
3

Carga el extension.neon

En phpstan.neon incluye la configuración de Larastan.

Configuración de phpstan.neon

phpstan.neon es el archivo central donde declaras el nivel de análisis, los paths a analizar, los excluidos y las reglas de excepción. En un paquete Laravel, es más realista empezar con una configuración que puedas ir endureciendo poco a poco que apuntar a la perfección desde el primer día. Ejemplo de phpstan.neon:

Cómo elegir el nivel 0–9

PHPStan permite ir subiendo poco a poco. Es más seguro empezar por el nivel más alto que puedas ejecutar limpiamente y elevarlo a medida que arreglas problemas.
PHPStan 2.x incluye el nivel 10, pero en paquetes Laravel es realista estabilizar primero 5–7 y luego pasar a 8–9. En un paquete nuevo puedes arrancar en un nivel más alto para no tener que volver atrás.

paths

En paths declara explícitamente los directorios a analizar. En los paquetes es útil incluir no solo src, sino también tests, donde suele romperse la tipificación.

excludePaths

Excluye solo lo que no aporta al análisis (archivos generados, caché, el Workbench de verificación…). Si excluyes demasiado, dejarás fuera errores que sí querías detectar.

ignoreErrors

ignoreErrors es el último recurso. Restringe el mensaje con una expresión regular y usa también path para limitar el alcance. Así podrás retirar la excepción con facilidad si Laravel o Larastan mejoran en el futuro.

Anotaciones de tipo habituales

La precisión de PHPStan y Larastan depende mucho de cómo escribas los PHPDoc. En un paquete Laravel merece especialmente la pena cuidar @param, @return, @var y los generics (@template).
En este ejemplo, se le pasa a PHPStan la siguiente información:
  • @param class-string<TModel> — indica que la cadena no es cualquiera, sino el nombre de una clase Model.
  • @return TModel|null — comunica que find() devuelve el tipo concreto del modelo.
  • @var Collection<int, TModel> — explicita los tipos de clave y valor de la colección.
  • @template TModel of Model — expresa un repositorio genérico reutilizable.

Consideraciones específicas de Laravel

La «magia» cómoda de Laravel no se transmite tal cual al análisis estático. Debes añadir información de tipos desde el paquete para que el analizador pueda entenderla.

Facades

En facades personalizadas, describir con PHPDoc los métodos que el usuario invocará mejora tanto el IDE como el análisis estático.

Métodos mágicos

Las APIs basadas en __call() o Macroable son cómodas, pero rompen fácilmente los tipos. Si van a formar parte de tu API pública, es más seguro añadir métodos wrapper explícitos con tipos claros de argumentos y retorno.
Si engordas ignoreErrors solo para satisfacer al analizador, ocultarás cómo se rompen realmente tus facades y macros. Prioriza soluciones basadas en métodos explícitos, value objects tipados o mejor PHPDoc.

Tipar modelos Eloquent

Para las relaciones Eloquent y las propiedades dinámicas, combinar @property con generics de relación funciona muy bien.

Ejecución automática en CI

Ejecuta el análisis estático no solo en local, sino también en CI. Sobre todo si el paquete soporta varias versiones de Laravel, aplica la misma idea que la test matrix descrita en Gestión de la compatibilidad de versiones de paquetes: así vigilas compatibilidad y seguridad de tipos a la vez. Ejemplo de .github/workflows/static-analysis.yml:
En este ejemplo se usa la misma tabla de compatibilidad Laravel / Testbench que la matriz de tests. Monitorizar la misma combinación en tests y análisis estático te ayuda a que no pase desapercibido el caso «se ejecuta pero los tipos están rotos».

Falsos positivos frecuentes y cómo tratarlos

Ante un warning de análisis estático, sospecha primero de la información de tipos: aunque parezca un falso positivo, muchas veces es simplemente PHPDoc insuficiente.

@phpstan-ignore-next-line

Sirve como parche puntual, pero úsalo solo en líneas donde puedas explicar el motivo.

ignoreErrors

Considéralo solo cuando el mismo error aparece en varios sitios. Restringe siempre el path y no uses expresiones regulares laxas que silencien todo.

Prioridades al resolver un aviso

  1. Añadir PHPDoc.
  2. Declarar el tipo de retorno de facades y relaciones.
  3. Sustituir mixed por tipos concretos.
  4. Solo entonces, ignorar los falsos positivos que puedas explicar.

Páginas relacionadas

Desarrollo de paquetes Laravel

Fundamentos de implementación de paquetes, incluyendo service providers y recursos publicados.

Probar paquetes Laravel con Orchestra Testbench

Base de pruebas ideal para combinar con análisis estático.

Gestión de la compatibilidad de versiones de paquetes

Estrategia para la tabla de compatibilidad Laravel / PHP y la matriz de GitHub Actions.
Última modificación el 13 de julio de 2026