Laravel 13.34.0 est sorti le 30 septembre 2026. Cette version modifie le traitement des échecs dans les queues et apporte plusieurs corrections à l’ORM, aux outils de schéma, aux tests, au cache et aux intégrations de plateforme.
use Illuminate\Queue\Attributes\CountCrashesAsExceptions;
use Illuminate\Queue\Attributes\MaxExceptions;
#[MaxExceptions(3), CountCrashesAsExceptions]
class ProcessPodcast implements ShouldQueue
{
public function retryUntil(): DateTime
{
return now()->addHour();
}
}William Julian-Vicary a ajouté l’attribut optionnel CountCrashesAsExceptions pour les jobs en queue. Une exception lancée était déjà comptabilisée dans la valeur $maxExceptions. Un worker arrêté par un manque de mémoire, un défaut de segmentation ou l’arrêt d’un conteneur ne comptait pas comme une exception. Un job utilisant retryUntil() avec un rate limiter pouvait donc continuer à faire tomber des workers jusqu’à l’expiration de son délai.
Avec ce nouvel attribut, une tentative interrompue par un crash compte comme une exception. La propriété publique $countCrashesAsExceptions = true offre le même comportement. Le worker crée une clé de cache au démarrage d’un job concerné, puis la supprime quand la tentative se termine. Si la clé existe encore lors de la tentative suivante, Laravel considère que l’exécution précédente s’est terminée par un crash du worker. Le job doit définir maxExceptions. Chaque tentative ajoute deux accès au cache, ce qui explique le caractère optionnel de la fonctionnalité. La modification correspond à la pull request #61737.
Jack Bayliss a modifié la gestion des délais pour les jobs qui implémentent Illuminate\Contracts\Queue\Interruptible. Lorsque le délai expire, le worker envoie maintenant SIGALRM. La méthode interrupted() peut ainsi sauvegarder l’avancement avant l’échec du job. Les versions précédentes transmettaient des signaux comme SIGTERM pour d’autres interruptions. Un timeout pouvait toutefois arrêter le worker sans prévenir le job.
Le worker déclenche également JobInterrupted, un événement introduit dans Laravel 13.31. Les exceptions lancées par interrupted() sont signalées pendant que le timeout poursuit son traitement. Cette évolution figure dans la pull request #61651.
L’événement JobProcessed possède désormais une propriété duration exprimée en millisecondes. Lorsqu’il provient d’un worker, la valeur est un nombre flottant arrondi à deux décimales. Elle vaut null si l’événement est déclenché ailleurs. Les applications peuvent donc mesurer la durée sans associer systématiquement JobProcessing et JobProcessed. La pull request #61672 a ajouté cette propriété.
La commande queue:flush accepte maintenant --queue. Elle peut supprimer les jobs en échec d’une seule queue et préserver ceux des autres. L’option se combine avec --hours, par exemple queue:flush --queue=sftp-sync --hours=48, afin de conserver les échecs récents. Cette évolution est documentée dans la pull request #61630.
Schema::getColumn('users', 'email') renvoie les informations d’une colonne précise. Le résultat comprend notamment type_name et nullable. Une colonne inexistante produit un tableau vide. La méthode a été ajoutée par la pull request #61759.
assertDatabaseCount() accepte désormais un tableau de couples table et quantité. Un test peut vérifier plusieurs modèles Eloquent ou noms de tables dans une seule assertion. La pull request #61727 couvre ce changement.
App::environment() et la méthode environments() du planificateur acceptent maintenant les enums. La directive Blade @env en bénéficie aussi, puisqu’elle est compilée via App::environment(). Queue::isPaused() accepte également les enums, comme Queue::pause() et Queue::resume(). Auparavant, un enum transmis à App::environment() provoquait une erreur. Dans environments(), il pouvait empêcher l’exécution d’une tâche planifiée. Ces changements correspondent aux pull requests #61730 et #61725.
Relation::requireMorphMap() contrôle désormais aussi la lecture des relations polymorphes. Laravel rejetait déjà l’enregistrement d’un modèle dépourvu d’entrée dans la morph map. Le chargement différé ou anticipé lève maintenant ClassMorphViolationException lorsqu’une valeur *_type n’est pas présente dans la map. Les applications qui n’activent pas requireMorphMap() conservent leur comportement précédent. La pull request #61711 a ajouté cette vérification.
Le reste de la version 13.34.0 regroupe des corrections et des ajustements de compatibilité. Les valeurs de LazyCollection sont acceptées dans les clauses between (#61678), et LazyCollection::combine() lève ValueError lorsque les longueurs diffèrent (#61696). Les attributs actualisés sont resynchronisés avec l’état original après increment ou decrement. Ils sont exclus lors de la réplication des modèles (#61680, #61751). Number::parseInt() gère les valeurs supérieures à la limite 32 bits. Number::format(), percentage() et currency() ne renvoient plus -0 (#61691, #61716). Collection::mode() traite correctement les valeurs nulles (#61686), shift($count) renvoie une collection vide sur une collection source vide (#61723), et trans_choice() choisit la bonne forme plurielle pour les nombres négatifs (#61700).
PhpRedisLock::refresh() fonctionne avec la sérialisation phpredis activée (#61690). DatabaseLock ne masque plus les deadlocks dans une transaction (#61708). sortBy() conserve les valeurs fractionnaires avec plusieurs colonnes et SORT_NUMERIC (#61699). Les nouvelles tentatives de requêtes multipart conservent le contenu des flux attachés (#61728). Eloquent whereNot() n’applique plus une double négation aux conditions sous forme de tableau (#61721). Les requêtes de relations respectent la clé propriétaire dans whereMorphedTo() et whereNotMorphedTo() (#61712). wherePivotBetween() fonctionne avec sync(), detach() et updateExistingPivot() (#61747). through() ne renvoie plus HasOneThrough pour une relation MorphMany (#61760), et findOrFail() gère les tableaux d’identifiants enum (#61765).
La commande queue:restart affiche désormais une erreur lorsque le worker ne peut pas être redémarré (#61706). Laravel ajoute des Cloud exceptions (#61704), les fournisseurs d’identifiants S3 nommés et les disques Cloud IAM (#61676), ainsi que la prise en charge de phpstan/phpstan:2.2.15 (#61719). Les options PDO existantes sont conservées avec Cloud Postgres en pool lorsque les requêtes préparées émulées sont forcées (#61735). Les verrous Memcached de plus de 30 jours n’expirent plus immédiatement (#61742). Le throttling Redis ne renvoie plus un horodatage comme nombre de tentatives restantes (#61748). Un test de régression couvre désormais createPayloadUsing dans le gestionnaire de queue (#61773).
La directive Blade elsePushIf gère les conditions complexes (#61741). ArrayStore::touch() traite littéralement les clés contenant des points (#61777). memoized tagged-cache many() ne renvoie plus null pour les clés numériques (#61780). Les détails des fichiers signalés incluent leur type MIME (#61772). Les exclusions du validateur utilisent des recherches à temps constant (#61698). La version comprend aussi des corrections Markdown (#61746), un dernier nettoyage de Mockery (#61739), des mises à jour de documentation et de tests (#61679, #61683, #61697, #61663), ainsi que des corrections StyleCI (#61763).
Les workflows CI s’exécutent maintenant sous Windows 2025. Un test de planification instable sous Windows a été corrigé (#61718, #61768). L’extension Imagick est explicitement activée pour les tests CI (#61756).




Commentaires
Pas encore de commentaire — écris le premier.
Lance la discussion
Pas de compte ni de mot de passe — saisis simplement ton adresse e-mail et nous t’envoyons un lien de connexion à usage unique. Première visite ? Tout se met en place automatiquement.
Ton évaluation sera appliquée automatiquement après ta connexion.
Vérifie ta boîte mail
Nous avons envoyé un lien de connexion à …. Ouvre-le sur cet appareil — cet onglet te connectera automatiquement.
Rien reçu ? Vérifiez le dossier spam — et marquez le message « Non spam » pour qu'il arrive directement la prochaine fois.