Desarrollo Web 5-8 minutos

Análisis estático en Laravel 13 con Larastan y PHPStan

Diego Cortés
Diego Cortés
Full Stack Developer & SEO Specialist
Compartir:
Análisis estático en Laravel 13 con Larastan y PHPStan
Imagen generada con IA

Larastan, la extensión de PHPStan para Laravel, detecta errores en facades, Eloquent y colecciones sin ejecutar una línea: se instala con un composer require y se integra en CI para que cada push revise tu código. El análisis estático en Laravel 13 es la vía para menos bugs en producción.

Qué es el análisis estático y por qué Laravel lo necesita

El análisis estático examina el código sin ejecutarlo: recorre tus clases, métodos y llamadas, y señala inconsistencias de tipos, argumentos mal pasados o accesos a propiedades que no existen. Es un revisor que trabaja en milisegundos y no se salta nada, justo lo que un humano se pierde en una tarde de review.

PHPStan: el analizador que entiende PHP sin ejecutarlo

PHPStan es el motor de análisis estático más popular de PHP. No ejecuta tu aplicación: la lee y construye un modelo de qué tipos fluyen por cada variable, parámetro y retorno, para avisarte cuando algo no cuadra. Cuanto más estricto sea el nivel configurado, más reglas aplica y más fino es el colador.

Qué aporta Larastan: facades, Eloquent y colecciones

El problema es que Laravel está lleno de "magia": las facades resuelven clases en tiempo de ejecución, Eloquent crea propiedades dinámicas a partir de las columnas de la base de datos y las colecciones usan genéricos. PHPStan por sí solo no entiende esa magia, así que o bien ignoraba el código o llenaba de falsos positivos. Larastan enseña a PHPStan las reglas de Laravel: entiende las facades, tipa las propiedades de Eloquent y valida los genéricos de las colecciones. El resultado es que el análisis se enfoca en errores reales de tu código.

Instalar Larastan en Laravel 13

La instalación es un solo comando y la configuración inicial cabe en tres líneas. No necesitas tocar tu aplicación, solo añadir una dependencia de desarrollo.

composer require --dev larastan/larastan:^3.0

Larastan v3 es la versión actual, compatible con PHPStan 2.x y con Laravel 11.15 o superior, así que Laravel 13 (que corre sobre PHP 8.3+) queda cubierto de sobra. Se instala como dependencia de desarrollo:

composer require --dev "larastan/larastan:^3.0"

Al ser --dev, no engorda el autoload de producción ni se instala en los despliegues con composer install --no-dev.

phpstan.neon: includes, paths y level

Luego creas phpstan.neon en la raíz del proyecto con la configuración mínima:

includes:
    - vendor/larastan/larastan/extension.neon

parameters:
    paths:
        - app
    level: 5

El includes carga las reglas de Larastan, paths indica qué carpetas analizar y level fija el nivel de estrictez. Con esto ya puedes ejecutar el análisis:

vendor/bin/phpstan analyse --no-progress

Empezar en el nivel correcto

PHPStan define diez niveles, del 0 al 9, y cada uno añade reglas más estrictas sobre el anterior. No hay un nivel "correcto" universal: hay un nivel correcto para cada proyecto y momento.

Los niveles de PHPStan: de 0 a 9

El nivel 0 hace comprobaciones básicas de tipos y llamadas a funciones conocidas. Subir de nivel significa exigir más: chequeo de tipos en propiedades y retornos, manejo de valores nullable, tipos de arrays, y en los niveles altos, genéricos correctos en colecciones y llamadas a métodos sobre tipos que podrían ser null. El 9 es el techo y el más estricto de todos.

Nivel 5 vs nivel 9: qué ganas con cada uno

El nivel 5 es un punto de partida excelente: atrapa la mayoría de los bugs reales sin ahogarte en detalles de tipado. El nivel 9, en cambio, exige rigor total: en Laravel el dolor más común al subir son las colecciones, porque hay que tipar los genéricos de forma explícita. Si tu equipo es pequeño o el proyecto es legacy, empieza en 5 y sube cuando el código aguante; si el proyecto es nuevo, plantea el 9 como meta a medio plazo.

Errores que Larastan detecta (con ejemplos)

Ver el análisis funcionar sobre errores concretos es la mejor manera de entender su valor. Estos tres son los clásicos que Larastan atrapa antes de que lleguen a producción.

Propiedades dinámicas de Eloquent

Un modelo Eloquent expone sus columnas como propiedades, pero PHP no las conoce a nivel estático. Larastan usa los docblocks de los modelos para saber qué columnas existen:

/** @property string $name */
class User extends Model {}

Con eso, un acceso a $user->nmae deja de ser un error silencioso en runtime y se convierte en un error de análisis al instante. El typo que antes reventaba en producción, ahora aparece en tu terminal.

Facades y métodos mágicos

Las facades delegan en clases subyacentes mediante métodos mágicos, algo que PHPStan no puede rastrear sin ayuda. Larastan conoce la correspondencia facade-clase real, así que una llamada a un método que no existe en Cache:: o DB:: se detecta en análisis estático, no cuando el usuario la dispara.

Colecciones y genéricos: el dolor del nivel 9

Las colecciones son la zona donde más proyectos se atascan en los niveles altos. collect([1, 2, 3]) devuelve una colección de enteros, y PHPStan quiere saberlo:

/** @var Collection<int, User> $users */
$users = User::all();

Con el tipo declarado, métodos como first() o map() devuelven tipos conocidos y el análisis valida las cadenas completas. Sin la declaración, en nivel 9 todo son quejas de genéricos.

El baseline: análisis estático en proyectos legacy

Adoptar análisis estático en una codebase legacy asusta porque el primer análisis suele devolver cientos de errores. El baseline existe exactamente para eso: congelar el estado actual y avanzar sin detener la entrega.

vendor/bin/phpstan analyse --generate-baseline

El comando genera un archivo con todos los errores actuales:

vendor/bin/phpstan analyse --generate-baseline

Crea phpstan-baseline.neon con la lista de errores existentes. Al incluirlo en phpstan.neon, PHPStan ignora esos errores congelados pero sigue fallando ante cualquier error nuevo. Es la forma de empezar a analizar hoy sin tener que arreglar un año de deuda técnica mañana.

Subir de nivel progresivamente sin parar la entrega

Con el baseline activo, el equipo puede ir quemando errores poco a poco: cada PR corrige algunos, el archivo baseline se regenera y el nivel puede subir cuando el número de errores congelados baja. Es un camino realista para llegar de nivel 0 a nivel 9 en un proyecto que lleva años en producción, sin bloquear el desarrollo en ningún momento.

Larastan en CI con GitHub Actions

El análisis estático solo cumple su función si corre en cada cambio, y ahí es donde entra CI. Un job de GitHub Actions que ejecute PHPStan en cada push convierte la revisión en algo automático y obligatorio.

El job de análisis en cada push

Un job mínimo se ve así:

name: Static Analysis
on: [push]

jobs:
  phpstan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.3'
      - run: composer install --no-interaction --prefer-dist
      - run: vendor/bin/phpstan analyse --no-progress

Si el análisis encuentra errores, el job falla y el PR no se puede fusionar. A partir de ahí, el flujo es el mismo en GitLab CI o Travis: un paso más en el pipeline y el nivel de calidad queda garantizado por la herramienta, no por la memoria del equipo.

Proyectos nuevos: sin baseline desde el día uno

Si arrancas un proyecto nuevo, no necesitas baseline: configuras el nivel alto desde el primer commit y el análisis exige código limpio desde el principio. Es mucho más barato mantener el nivel 9 en un proyecto de un mes que alcanzarlo en uno de tres años.

Larastan + Laravel Pint: calidad de código completa

Es importante entender qué hace cada herramienta: Larastan encuentra errores de tipos y llamadas, no arregla estilo. Para formateo y convenciones de código entra Laravel Pint, el formateador oficial de Laravel basado en PHP-CS-Fixer. La combinación funciona como un revisor de código automático permanente: Pint mantiene el estilo uniforme y Larastan vela por la corrección de tipos, los dos sin intervención humana y ejecutándose en cada push.

Conclusión

Larastan lleva el análisis estático a Laravel 13 y convierte PHPStan en un revisor que entiende facades, Eloquent y colecciones: se instala con un comando, se configura en tres líneas y se integra en CI para que cada push revise tu código. Empieza en un nivel bajo, usa el baseline si tienes legacy y sube de nivel con calma. Si ya automatizas tus despliegues con GitHub Actions o acabas de migrar a Laravel 13, este es el complemento que te falta antes de que los bugs lleguen a producción.

Categorías