> ## Documentation Index
> Fetch the complete documentation index at: https://kawax.biz/llms.txt
> Use this file to discover all available pages before exploring further.

# Actualización de Laravel 9 a 10

> Explicación de los pasos de actualización de Laravel 9.x a 10.x y de los principales cambios.

## 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.

<Info>
  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.
</Info>

### Actualización automatizada con Laravel Shift

Puedes automatizar la actualización con [Laravel Shift](https://laravelshift.com/). 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`.

```json theme={null}
{
  "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.

```json theme={null}
{
  "require": {
    "laravel/passport": "^11.0",
    "laravel/ui": "^4.0"
  }
}
```

Si vas a usar PHPUnit 10, actualiza también lo siguiente.

```json theme={null}
{
  "require-dev": {
    "nunomaduro/collision": "^7.0",
    "phpunit/phpunit": "^10.0"
  }
}
```

<Warning>
  Si usas PHPUnit 10, elimina el atributo `processUncoveredFiles` de la sección `<coverage>` de `phpunit.xml`.
</Warning>

Después, instala las dependencias con el siguiente comando.

```shell theme={null}
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](https://github.com/laravel/sanctum/blob/3.x/UPGRADE.md).

***

### 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.

```json theme={null}
"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`.

```php theme={null}
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)`.

```php theme={null}
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`.

```php theme={null}
// 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`.

```php theme={null}
// 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.

```shell theme={null}
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](https://github.com/Seldaek/monolog/blob/main/UPGRADE.md).

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.

<Tip>
  Los cambios de Monolog 3.x se pueden consultar en la [guía de actualización de Monolog 3.x](https://github.com/Seldaek/monolog/blob/3.x/UPGRADE.md).
</Tip>

***

### 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`.

```php theme={null}
// 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`.

```php theme={null}
$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.

```php theme={null}
// 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.

```php theme={null}
// 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.

```php theme={null}
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.

| Cambio                                              | Impacto  | Acción                                                    |
| --------------------------------------------------- | -------- | --------------------------------------------------------- |
| Actualización de dependencias en `composer.json`    | Alto     | Cambiar a `laravel/framework ^10.0`                       |
| PHP 8.1 / Composer 2.2 obligatorios                 | Alto     | Comprobar y actualizar versiones                          |
| Cambios en expresiones de base de datos             | Medio    | Cambiar el cast a `(string)` por `getValue()`             |
| Eliminación de la propiedad `$dates` de los modelos | Medio    | Migrar a `$casts`                                         |
| Monolog 3                                           | Medio    | Si lo usas directamente, revisar la guía de actualización |
| Tags de caché en Redis                              | Medio    | Considerar la migración a Memcached                       |
| Eliminación de `MocksApplicationServices`           | Medio    | Migrar a `Event::fake`, etc.                              |
| Eliminación de `Bus::dispatchNow`                   | Bajo     | Cambiar a `Bus::dispatchSync`                             |
| Nombre de columna ULID                              | Bajo     | Revisar las llamadas a `ulid()` en migraciones            |
| Eliminación de `Redirect::home`                     | Muy bajo | Cambiar a `Redirect::route('home')`                       |

***

## Referencias

* [Guía oficial de actualización (inglés)](https://laravel.com/docs/10.x/upgrade)
* [Diff del repositorio laravel/laravel (9.x → 10.x)](https://github.com/laravel/laravel/compare/9.x...10.x)
* [Laravel Shift](https://laravelshift.com): servicio comunitario que automatiza la actualización
* [Guía de actualización de Sanctum (2.x → 3.x)](https://github.com/laravel/sanctum/blob/3.x/UPGRADE.md)
* [Guía de actualización de Monolog 3.x](https://github.com/Seldaek/monolog/blob/3.x/UPGRADE.md)


## Related topics

- [Actualización de Laravel 10 a 11](/es/blog/upgrade-10-to-11.md)
- [Guía de actualización de Laravel 12 a 13](/es/blog/upgrade-12-to-13.md)
- [Actualización de Laravel 8 a 9](/es/blog/upgrade-8-to-9.md)
- [Actualización de Laravel — Mayo de 2026](/es/blog/changelog/202605.md)
- [Actualización de Laravel — Marzo de 2026](/es/blog/changelog/202603.md)
