Saltar al contenido principal

Introducción

Laravel 10 se lanzó el 14 de febrero de 2023. Esta guía explica los pasos para actualizar de Laravel 9.x a 10.x.
El tiempo estimado necesario para la actualización es de unos 10 minutos. Sin embargo, el impacto de los cambios disruptivos en tu aplicación varía según el tamaño y las funcionalidades utilizadas.

Actualización automatizada con Laravel Shift

Puedes automatizar la actualización con Laravel Shift. Shift actualiza automáticamente las dependencias y los archivos de configuración de tu aplicación.

Cambios por nivel de impacto

Impacto: alto

  • Actualización de dependencias
  • Actualización de minimum-stability

Impacto: medio

  • Cambios en las expresiones de base de datos
  • Eliminación de la propiedad $dates de los modelos
  • Monolog 3
  • Tags de caché en Redis
  • Cambios en el mocking de servicios
  • Directorio de idiomas

Impacto: bajo

  • Mensajes de reglas de validación con closures
  • Método after en form requests
  • Binding de la ruta pública
  • Constructor de QueryException
  • Valor de retorno del rate limiter
  • Eliminación del método Redirect::home
  • Eliminación del método Bus::dispatchNow
  • Método registerPolicies
  • Columna ULID

Pasos de actualización

Actualización de dependencias

Impacto: alto Actualiza las siguientes dependencias en composer.json.
{
  "require": {
    "laravel/framework": "^10.0",
    "laravel/sanctum": "^3.2",
    "doctrine/dbal": "^3.0",
    "spatie/laravel-ignition": "^2.0"
  }
}
Si usas paquetes, actualízalos también.
{
  "require": {
    "laravel/passport": "^11.0",
    "laravel/ui": "^4.0"
  }
}
Si vas a usar PHPUnit 10, actualiza también lo siguiente.
{
  "require-dev": {
    "nunomaduro/collision": "^7.0",
    "phpunit/phpunit": "^10.0"
  }
}
Si usas PHPUnit 10, elimina el atributo processUncoveredFiles de la sección <coverage> de phpunit.xml.
Después, instala las dependencias con el siguiente comando.
composer update
Para la actualización de Sanctum 2.x a 3.x, consulta también la guía de actualización de Sanctum 3.x.

Actualización de minimum-stability

Impacto: alto Actualiza minimum-stability en composer.json a stable. Como el valor por defecto es stable, también puedes eliminar esta línea.
"minimum-stability": "stable"

Requisitos de versión de PHP

Impacto: alto Laravel 10 requiere PHP 8.1.0 o superior y Composer 2.2.0 o superior.

Cambios disruptivos (Breaking Changes)

Aplicación

Binding de la ruta pública

Impacto: bajo Si personalizabas la ruta pública haciendo binding de path.public en el contenedor, cámbialo para usar el método usePublicPath de Illuminate\Foundation\Application.
app()->usePublicPath(__DIR__.'/public');

Autorización

Método registerPolicies

Impacto: bajo El método registerPolicies del AuthServiceProvider lo llama ahora el framework automáticamente. Puedes eliminar la llamada a este método en boot.

Caché

Tags de caché en Redis

Impacto: medio Cache::tags() solo se recomienda para aplicaciones que usan Memcached. Si usas Redis como driver de caché, considera migrar a Memcached.

Base de datos

Cambios en las expresiones de base de datos

Impacto: medio Las expresiones de base de datos generadas con DB::raw se han reescrito. Para obtener el valor bruto de cadena de la expresión hay que usar el método getValue(Grammar $grammar). Ya no se puede usar el cast a (string).
use Illuminate\Support\Facades\DB;

$expression = DB::raw('select 1');

// Antes
$string = (string) $expression;

// Después
$string = $expression->getValue(DB::connection()->getQueryGrammar());
Normalmente no afecta a las aplicaciones de usuario final, pero si tienes cast a string sobre expresiones de base de datos, actualízalo.

Constructor de QueryException

Impacto: muy bajo Se ha añadido un primer argumento con el nombre de conexión (string) al constructor de Illuminate\Database\QueryException. Si lanzas esta excepción manualmente, corrige el código.

Columna ULID

Impacto: bajo Si en una migración llamas al método ulid sin argumentos, el nombre de la columna es ulid. En releases anteriores, al llamarlo sin argumentos se creaba por error una columna con nombre uuid.
// El nombre de la columna pasa a ser "ulid"
$table->ulid();

// Si quieres indicar el nombre de columna explícitamente
$table->ulid('ulid');

Eloquent

Propiedad $dates de los modelos

Impacto: medio Se ha eliminado la propiedad obsoleta $dates de los modelos Eloquent. Usa la propiedad $casts.
// Antes
protected $dates = ['deployed_at'];

// Después
protected $casts = [
    'deployed_at' => 'datetime',
];

Localización

Directorio de idiomas

Impacto: ninguno No afecta a las aplicaciones existentes, pero el esqueleto de las nuevas aplicaciones Laravel ya no incluye el directorio lang por defecto. Si lo necesitas, puedes publicarlo con un comando Artisan.
php artisan lang:publish

Log

Monolog 3

Impacto: medio La dependencia Monolog de Laravel se ha actualizado a Monolog 3.x. Si usas Monolog directamente en la aplicación, consulta la guía de actualización de Monolog. Si usas servicios de logging de terceros como BugSnag o Rollbar, puede que necesites actualizar a versiones que soporten Monolog 3.x y Laravel 10.x.
Los cambios de Monolog 3.x se pueden consultar en la guía de actualización de Monolog 3.x.

Cola

Eliminación del método Bus::dispatchNow

Impacto: bajo Se han eliminado los métodos obsoletos Bus::dispatchNow y dispatch_now. Usa Bus::dispatchSync y dispatch_sync.
// Antes
Bus::dispatchNow(new MyJob());
dispatch_now(new MyJob());

// Después
Bus::dispatchSync(new MyJob());
dispatch_sync(new MyJob());

Enrutamiento

Alias de middleware

Impacto: opcional En las nuevas aplicaciones Laravel, la propiedad $routeMiddleware de la clase App\Http\Kernel se ha renombrado a $middlewareAliases. Aplicarlo a aplicaciones existentes es opcional.

Valor de retorno del rate limiter

Impacto: bajo Al llamar al método RateLimiter::attempt, ahora se devuelve tal cual el valor de retorno del closure suministrado. Si no devuelves nada o devuelves null, se devuelve true.
$value = RateLimiter::attempt('key', 10, fn () => ['example'], 1);

$value; // ['example']

Eliminación del método Redirect::home

Impacto: muy bajo Se ha eliminado el método obsoleto Redirect::home. Cambia a redirección explícita a una ruta con nombre.
// Antes
return Redirect::home();

// Después
return Redirect::route('home');

Testing

Mocking de servicios

Impacto: medio Se ha eliminado del framework el trait obsoleto MocksApplicationServices. Este trait proporcionaba métodos de test como expectsEvents, expectsJobs, expectsNotifications, etc. Si usas estos métodos, migra a Event::fake, Bus::fake y Notification::fake respectivamente.
// Antes
$this->expectsEvents(OrderShipped::class);

// Después
Event::fake();
// ... código de test ...
Event::assertDispatched(OrderShipped::class);

Validación

Mensajes de reglas de validación con closures

Impacto: muy bajo En reglas de validación personalizadas basadas en closure, si llamas varias veces al callback $fail, los mensajes se añaden a un array en lugar de sobrescribirse. Además, el callback $fail devuelve ahora un objeto. Si tenías type hint sobre el valor de retorno del closure de validación, actualízalo.
public function rules()
{
    return [
        'name' => [
            function ($attribute, $value, $fail) {
                $fail('validation.translation.key')->translate();
            },
        ],
    ];
}

Método after en form requests

Impacto: muy bajo El método after dentro de form requests está reservado por Laravel. Si tienes definido un método after en un form request, renómbralo o modifícalo para aprovechar la nueva funcionalidad “post-validación”.

Conclusión

Laravel 10 está compuesto por cambios relativamente pequeños y la actualización se puede completar en poco tiempo.
CambioImpactoAcción
Actualización de dependencias en composer.jsonAltoCambiar a laravel/framework ^10.0
PHP 8.1 / Composer 2.2 obligatoriosAltoComprobar y actualizar versiones
Cambios en expresiones de base de datosMedioCambiar el cast a (string) por getValue()
Eliminación de la propiedad $dates de los modelosMedioMigrar a $casts
Monolog 3MedioSi lo usas directamente, revisar la guía de actualización
Tags de caché en RedisMedioConsiderar la migración a Memcached
Eliminación de MocksApplicationServicesMedioMigrar a Event::fake, etc.
Eliminación de Bus::dispatchNowBajoCambiar a Bus::dispatchSync
Nombre de columna ULIDBajoRevisar las llamadas a ulid() en migraciones
Eliminación de Redirect::homeMuy bajoCambiar a Redirect::route('home')

Referencias

Última modificación el 13 de julio de 2026