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

# Guide de mise à niveau de Laravel 11 à 12

> Procédure de mise à niveau de Laravel 11 à 12 et principaux changements.

## Introduction

Laravel 12 est sorti en février 2025. Ce guide explique la procédure de mise à niveau de Laravel 11.x vers 12.x.

<Info>
  Le temps estimé est d'**environ 5 minutes**. L'impact des changements cassants dépend de la taille de l'application et des fonctionnalités utilisées.
</Info>

### Mise à niveau automatisée avec Laravel Shift

Vous pouvez automatiser la mise à niveau avec [Laravel Shift](https://laravelshift.com/).

***

## Changements par impact

### Impact élevé

* Mise à jour des dépendances
* Mise à jour de l'installer Laravel

### Impact moyen

* Trait Eloquent `HasUuids` et UUIDv7

### Impact faible

* Carbon 3
* Mapping d'index des résultats Concurrency
* Résolution des dépendances de classe du conteneur
* Exclusion des SVG dans la validation `image`
* Chemin racine par défaut du disque local
* Introspection multi-schémas
* Merge de tableaux imbriqués dans une requête

***

## Étapes de mise à niveau

### Mise à jour des dépendances

**Impact : élevé**

Mettez à jour les dépendances suivantes dans `composer.json`.

```json theme={null}
{
  "require": {
    "laravel/framework": "^12.0"
  },
  "require-dev": {
    "phpunit/phpunit": "^11.0",
    "pestphp/pest": "^3.0"
  }
}
```

Installez :

```shell theme={null}
composer update
```

***

### Mise à jour de l'installer Laravel

**Impact : élevé**

Si vous créez de nouvelles applications avec le CLI installer, mettez-le à jour pour la compatibilité avec Laravel 12.x et les [nouveaux starter kits](https://laravel.com/starter-kits).

Installé via `composer global require` :

```shell theme={null}
composer global update laravel/installer
```

Installé via `php.new` : relancez la commande d'installation adaptée à votre OS.

<Tabs>
  <Tab title="macOS">
    ```shell theme={null}
    /bin/bash -c "$(curl -fsSL https://php.new/install/mac/8.4)"
    ```
  </Tab>

  <Tab title="Windows PowerShell">
    ```shell theme={null}
    # À exécuter en tant qu'administrateur
    Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://php.new/install/windows/8.4'))
    ```
  </Tab>

  <Tab title="Linux">
    ```shell theme={null}
    /bin/bash -c "$(curl -fsSL https://php.new/install/linux/8.4)"
    ```
  </Tab>
</Tabs>

Avec la version fournie par [Laravel Herd](https://herd.laravel.com), mettez Herd lui-même à jour.

***

## Nouveaux starter kits

Laravel 12 introduit de nouveaux starter kits qui remplacent Breeze et Jetstream. `laravel new` propose interactivement le choix de la stack frontend.

Starter kits disponibles :

* **React** — Inertia 2, React 19, TypeScript, Tailwind 4, shadcn/ui
* **Vue** — Inertia 2, Composition API, TypeScript, Tailwind 4, shadcn-vue
* **Svelte** — Inertia 2, Svelte 5, TypeScript, Tailwind 4, shadcn-svelte
* **Livewire** — Livewire, Tailwind 4, Flux UI

```shell theme={null}
laravel new my-app
```

Le choix du starter kit est demandé. Ensuite :

```shell theme={null}
cd my-app
npm install && npm run build
composer run dev
```

<Info>
  Aucune réinstallation de starter kit n'est nécessaire pour une application existante. Cela concerne les nouveaux projets.
</Info>

***

## Changements cassants

### Eloquent

#### Trait `HasUuids` et UUIDv7

**Impact : moyen**

Le trait `HasUuids` renvoie désormais des UUID v7 (ordonnés). Pour conserver l'ancien comportement (UUID v4 ordonnés), passez au trait `HasVersion4Uuids`.

```php theme={null}
use Illuminate\Database\Eloquent\Concerns\HasUuids; // [tl! remove]
use Illuminate\Database\Eloquent\Concerns\HasVersion4Uuids as HasUuids; // [tl! add]
```

Si vous utilisiez `HasVersion7Uuids`, remplacez-le par `HasUuids` (comportement identique).

***

### Validation

#### Exclusion des SVG dans la validation `image`

**Impact : faible**

La règle `image` n'autorise plus les SVG par défaut. Autorisez-les explicitement si nécessaire.

```php theme={null}
use Illuminate\Validation\Rules\File;

'photo' => 'required|image:allow_svg'

// ou
'photo' => ['required', File::image(allowSvg: true)],
```

***

### Stockage

#### Chemin racine par défaut du disque local

**Impact : faible**

Si le disque `local` n'est pas défini explicitement dans `filesystems`, le chemin racine par défaut passe de `storage/app` à `storage/app/private`.

Pour conserver l'ancien comportement, déclarez explicitement le disque `local` :

```php theme={null}
// config/filesystems.php
'local' => [
    'driver' => 'local',
    'root' => storage_path('app'),
],
```

***

### Base de données

#### Introspection multi-schémas

**Impact : faible**

`Schema::getTables()`, `Schema::getViews()`, `Schema::getTypes()` retournent désormais les résultats de tous les schémas par défaut. Passez `schema` pour cibler un schéma.

```php theme={null}
// Tables de tous les schémas
$tables = Schema::getTables();

// Tables du schéma 'main' uniquement
$tables = Schema::getTables(schema: 'main');
```

`Schema::getTableListing()` renvoie désormais des noms qualifiés par schéma par défaut.

```php theme={null}
$tables = Schema::getTableListing();
// ['main.migrations', 'main.users', 'blog.posts']

$tables = Schema::getTableListing(schema: 'main', schemaQualified: false);
// ['migrations', 'users']
```

#### Signature des constructeurs de base de données

**Impact : très faible**

Les constructeurs de `Illuminate\Database\Schema\Blueprint` et `Illuminate\Database\Grammar` requièrent désormais une instance `Connection` en premier argument.

```php theme={null}
// Laravel <= 11.x
$grammar = new MySqlGrammar;
$grammar->setConnection($connection);

// Laravel >= 12.x
$grammar = new MySqlGrammar($connection);
```

Par ailleurs, les API suivantes sont supprimées ou dépréciées.

| API                                              | État      |
| ------------------------------------------------ | --------- |
| `Blueprint::getPrefix()`                         | Déprécié  |
| `Connection::withTablePrefix()`                  | Supprimé  |
| `Grammar::getTablePrefix()` / `setTablePrefix()` | Dépréciés |
| `Grammar::setConnection()`                       | Supprimé  |

Récupérez le préfixe directement depuis la connexion.

```php theme={null}
$prefix = $connection->getTablePrefix();
```

***

### Concurrency

#### Mapping d'index des résultats

**Impact : faible**

Si vous passez un tableau associatif à `Concurrency::run()`, les résultats sont désormais renvoyés indexés par les mêmes clés.

```php theme={null}
$result = Concurrency::run([
    'task-1' => fn () => 1 + 1,
    'task-2' => fn () => 2 + 2,
]);

// ['task-1' => 2, 'task-2' => 4]
```

***

### Conteneur

#### Valeurs par défaut lors de la résolution de classes

**Impact : faible**

Le conteneur DI respecte désormais les valeurs par défaut des propriétés de classe lors de la résolution d'une instance.

```php theme={null}
class Example
{
    public function __construct(public ?Carbon $date = null) {}
}

$example = resolve(Example::class);

// Laravel <= 11.x : retourne une instance Carbon
// Laravel >= 12.x : retourne null
```

***

### Requêtes

#### Merge de tableaux imbriqués

**Impact : faible**

`$request->mergeIfMissing()` prend désormais en charge la notation dot pour fusionner des tableaux imbriqués. Auparavant, la clé en notation dot était créée telle quelle au niveau supérieur.

```php theme={null}
$request->mergeIfMissing([
    'user.last_name' => 'Otwell',
]);
```

***

### Routage

#### Priorité des routes

**Impact : faible**

Quand plusieurs routes portent le même nom, le comportement avec ou sans cache est désormais unifié. Sans cache, la première route enregistrée l'emporte (comme avec cache).

***

### Authentification

#### Signature de `DatabaseTokenRepository`

**Impact : très faible**

Le constructeur de `Illuminate\Auth\Passwords\DatabaseTokenRepository` accepte désormais `$expires` en secondes plutôt qu'en minutes.

***

### Carbon 3

**Impact : faible**

Le support de Carbon 2.x est supprimé. Toute application Laravel 12 requiert [Carbon 3.x](https://carbon.nesbot.com/guide/getting-started/migration.html).

***

## Conclusion

La mise à niveau vers Laravel 12 est relativement fluide.

| Changement                     | Impact | À faire                                    |
| ------------------------------ | ------ | ------------------------------------------ |
| Mise à jour de `composer.json` | Élevé  | `laravel/framework ^12.0`                  |
| Mise à jour de l'installer     | Élevé  | `composer global update`                   |
| `HasUuids` → UUIDv7            | Moyen  | Basculer vers `HasVersion4Uuids` si besoin |
| Validation `image` sans SVG    | Faible | `allow_svg` si SVG requis                  |
| Racine du disque local         | Faible | Déclarer explicitement dans la config      |
| Carbon 3 requis                | Faible | Vérifier la compatibilité API              |

***

## Ressources

* [Guide officiel (anglais)](https://laravel.com/docs/12.x/upgrade)
* [Diff du dépôt laravel/laravel (11.x → 12.x)](https://github.com/laravel/laravel/compare/11.x...12.x)
* [Nouveaux starter kits](https://laravel.com/starter-kits)
* [Laravel Shift](https://laravelshift.com) — automatisation communautaire des mises à niveau
* [Guide de migration Carbon 3](https://carbon.nesbot.com/guide/getting-started/migration.html)


## Related topics

- [Guide de mise à niveau de Laravel 12 vers 13](/fr/blog/upgrade-12-to-13.md)
- [Mise à niveau de Laravel 10 à 11](/fr/blog/upgrade-10-to-11.md)
- [Mise à niveau de Laravel 8 vers 9](/fr/blog/upgrade-8-to-9.md)
- [Mise à niveau de Laravel 9 vers 10](/fr/blog/upgrade-9-to-10.md)
- [Les nouveautés de Laravel 13](/fr/blog/laravel-13-new-features.md)
