Aller au contenu
← Retour au blog
interne FR

Passer de Laravel 12 à Laravel 13 : guide pratique de mise à jour

Publié le 2026-03-18 par Daniel Rubango

Laravel 13 a été conçu pour rester une mise à jour relativement simple depuis Laravel 12. Le guide officiel annonce un temps estimé d’upgrade d’environ 10 minutes pour la majorité des projets, tout en documentant les points à vérifier selon les cas particuliers. Source officielle : https://laravel.com/docs/13.x/upgrade

Cet article résume ce qu’il faut réellement faire, dans quel ordre, et les changements à surveiller pour éviter les régressions.


1. Avant de commencer : cadrer l’upgrade

Avant toute modification, l’objectif est de réduire le risque.

Checklist recommandée

  • créer une branche dédiée à l’upgrade
  • s’assurer que les tests existent et passent
  • vérifier la version de PHP
  • sauvegarder les fichiers de configuration sensibles
  • relire les dépendances maison qui étendent Laravel

Vérifications initiales

php -v
composer show laravel/framework
composer outdated
php artisan --version

Point de départ attendu

Laravel 13 exige PHP 8.3 minimum. Si votre environnement tourne encore sous PHP 8.2, il faut traiter cette étape avant le reste.


2. Mettre à jour les dépendances Composer

Le premier changement à appliquer se trouve dans composer.json.

Dépendances à mettre à jour

  • laravel/framework vers ^13.0
  • laravel/tinker vers ^3.0
  • phpunit/phpunit vers ^12.0
  • pestphp/pest vers ^4.0

Ensuite :

composer update

Conseil pratique

Si votre projet dépend de packages communautaires sensibles à la version du framework, exécutez aussi :

composer why-not laravel/framework 13.0

Cela aide à repérer rapidement un package qui bloque la montée de version.


3. Mettre à jour l’installer Laravel si vous l’utilisez

Si vous utilisez l’outil CLI laravel new, pensez aussi à mettre à jour l’installer.

composer global update laravel/installer

Si vous passez par Laravel Herd, mettez simplement Herd à jour.


4. Gérer le changement le plus important : PreventRequestForgery

C’est le point de plus fort impact dans le guide officiel.

Le middleware CSRF VerifyCsrfToken a été renommé en PreventRequestForgery. Les anciens alias existent encore, mais les références directes doivent être mises à jour.

Où vérifier dans votre projet

Recherchez les occurrences de :

  • VerifyCsrfToken::class
  • ValidateCsrfToken::class
  • exclusions de middleware sur des routes
  • helpers ou macros autour du middleware CSRF

Recherche rapide

grep -R "VerifyCsrfToken" app routes tests config

5. Vérifier la configuration du cache : serializable_classes

Laravel 13 ajoute par défaut une option de sécurité dans la config cache :

'serializable_classes' => false,

Cette mesure durcit le comportement de désérialisation pour limiter certains risques si APP_KEY fuit.

Quand cela peut casser

Si votre application met volontairement des objets PHP dans le cache, ils ne pourront plus être désérialisés librement.

Nouvelle approche recommandée

Déclarer explicitement les classes autorisées :

'serializable_classes' => [
    App\Data\CachedDashboardStats::class,
    App\Support\CachedPricingSnapshot::class,
],

Recommandation concrète

Dans la mesure du possible, préférez stocker des tableaux ou des payloads simples dans le cache plutôt que des objets riches.

Exemple :

Cache::put('dashboard.stats', [
    'users' => 1250,
    'sales' => 930,
    'growth' => 12.4,
], now()->addMinutes(30));

6. Vérifier les préfixes cache, Redis et le nom du cookie de session

Le guide signale un changement faible mais potentiellement piégeux si vous dépendez des valeurs générées par défaut.

Ancien comportement

Str::slug((string) env('APP_NAME', 'laravel'), '_').'_cache_';
Str::slug((string) env('APP_NAME', 'laravel'), '_').'_database_';
Str::slug((string) env('APP_NAME', 'laravel'), '_').'_session';

Nouveau comportement

Str::slug((string) env('APP_NAME', 'laravel')).'-cache-';
Str::slug((string) env('APP_NAME', 'laravel')).'-database-';
Str::snake((string) env('APP_NAME', 'laravel')).'_session';

Quand agir

Si votre application repose sur les valeurs de fallback du framework, alors vos clés Redis / cache et le cookie de session peuvent changer après l’upgrade.

Solution simple

Fixer explicitement les valeurs dans .env :

CACHE_PREFIX=myapp_cache_
REDIS_PREFIX=myapp_database_
SESSION_COOKIE=myapp_session

7. Vérifier les listeners liés aux événements de queue

Deux changements méritent un passage rapide.

JobAttempted : la propriété change

Avant :

$event->exceptionOccurred;

Après :

$event->exception;

QueueBusy : renommage de propriété

Avant :

$event->connection;

Après :

$event->connectionName;

Action recommandée

Recherchez vos listeners ou observateurs personnalisés :

grep -R "exceptionOccurred\|QueueBusy\|connectionName\|connection" app

8. Contrôler les requêtes MySQL DELETE ... JOIN

Laravel 13 compile désormais plus complètement certaines requêtes DELETE ... JOIN, y compris avec ORDER BY et LIMIT.

Pourquoi c’est sensible

Dans les versions précédentes, certains morceaux pouvaient être ignorés silencieusement. Avec Laravel 13, ils sont inclus dans le SQL généré. Résultat : certains moteurs peuvent maintenant lever une QueryException.

Exemple à auditer

DB::table('posts')
    ->join('users', 'users.id', '=', 'posts.user_id')
    ->where('users.inactive', true)
    ->orderBy('posts.id')
    ->limit(100)
    ->delete();

Recommandation

Passez en revue les suppressions complexes si votre projet manipule des requêtes SQL sophistiquées côté MySQL / MariaDB.


9. Éviter l’instanciation imbriquée pendant le boot des modèles

Créer une instance d’un modèle pendant qu’il est encore en phase de boot n’est plus autorisé.

Exemple problématique

protected static function boot()
{
    parent::boot();

    (new static())->getTable();
}

À faire à la place

Déplacer cette logique hors du cycle de boot.

Par exemple :

public static function tableName(): string
{
    return (new static())->getTable();
}

Puis l’appeler ailleurs que dans boot().


10. Vérifier les cas particuliers liés à la sérialisation Eloquent

Le guide signale que les collections Eloquent sérialisées puis restaurées récupèrent désormais aussi leurs relations eager-loaded.

Pourquoi c’est important

Si vous aviez du code qui partait du principe qu’après désérialisation certaines relations ne seraient pas présentes, ce comportement peut changer.

C’est surtout à tester dans :

  • les jobs queue
  • les notifications différées
  • les pipelines asynchrones

11. Vérifier les classes personnalisées qui implémentent des contrats Laravel

Si votre application ou vos packages maison implémentent certains contrats Laravel, l’upgrade impose quelques ajustements.

Contrats concernés dans le guide

  • Illuminate\Contracts\Cache\Store → ajout de touch
  • Illuminate\Contracts\Bus\Dispatcher → ajout de dispatchAfterResponse
  • Illuminate\Contracts\Routing\ResponseFactory → ajout de eventStream
  • Illuminate\Contracts\Auth\MustVerifyEmail → ajout de markEmailAsUnverified
  • Illuminate\Contracts\Queue\Queue → nouvelles méthodes d’inspection

Exemple pour un store de cache personnalisé

public function touch($key, $seconds)
{
    // Étendre le TTL de l’élément sans réécrire sa valeur
}

Exemple pour un MustVerifyEmail custom

public function markEmailAsUnverified()
{
    $this->forceFill([
        'email_verified_at' => null,
    ])->save();
}

12. Penser aux tests : Str factories, Unicode, sujets mail

Quelques changements de faible impact peuvent casser des tests trop stricts.

Cas à vérifier

  • réinitialisation des factories Str entre les tests
  • Js::from utilise désormais JSON_UNESCAPED_UNICODE
  • le sujet par défaut de réinitialisation de mot de passe change

Sujet mail

Avant :

Reset Password Notification

Après :

Reset your password

Action utile

Relancez toute la suite de tests et inspectez surtout :

  • les snapshots
  • les assertions de chaînes exactes
  • les sorties JS sérialisées
  • les tests mail / notifications

13. L’ordre conseillé pour une mise à jour propre

Voici un ordre simple et fiable.

Étape 1

Mettre PHP à jour vers 8.3 minimum.

Étape 2

Mettre à jour composer.json puis lancer :

composer update

Étape 3

Corriger les références à VerifyCsrfToken.

Étape 4

Vérifier la config cache, surtout serializable_classes et les préfixes.

Étape 5

Auditer les points sensibles :

  • listeners de queue
  • implémentations de contrats custom
  • Container::call
  • requêtes MySQL DELETE ... JOIN
  • sérialisation Eloquent

Étape 6

Exécuter les tests :

php artisan test

ou avec Pest :

./vendor/bin/pest

Étape 7

Tester manuellement les parcours critiques :

  • authentification
  • session
  • formulaires protégés CSRF
  • jobs asynchrones
  • cache
  • notifications
  • back-office

14. Peut-on automatiser la mise à jour ?

Oui. Le guide officiel mentionne deux pistes :

  • Laravel Shift, service communautaire d’automatisation d’upgrade
  • Laravel Boost, outil first-party orienté IA, avec la commande /upgrade-laravel-v13

Cela peut accélérer le travail, mais ne dispense pas de relire les changements qui touchent votre code métier.


Conclusion

La mise à jour de Laravel 12 vers Laravel 13 est globalement simple, mais elle mérite une vraie vérification sur quelques points précis.

Les éléments à surveiller en priorité sont :

  1. les dépendances Composer
  2. PHP 8.3 minimum
  3. PreventRequestForgery
  4. la configuration cache et serializable_classes
  5. les extensions personnalisées de contrats Laravel
  6. les listeners queue et certains comportements SQL / Eloquent

Si votre projet est proprement testé, l’upgrade devrait rester rapide. Le plus important n’est pas seulement de “faire passer Composer”, mais de sécuriser le comportement réel de l’application après migration.

Cet article vous présente quelques nouveautés de la version 13 : Nouveautés majeures à retenir.


Liens officiels

0

Commentaires

Aucun commentaire pour le moment.

Connectez-vous pour commenter.