Ce qui se passe
Laravel 13.36.0 est une version riche, dont deux changements agissent sans que le code change : la diffusion Mercure et l'échappement des mails Markdown. Les ajouts (validation, PlanetScale, files d'attente) sont tous optionnels.
Les deux changements à relire
Mercure diffuse en synchrone par défaut. Le diffuseur Mercure publie les
événements tout de suite, au lieu de les mettre en file. Un événement qui ne vise
que des connexions Mercure se comporte désormais comme ShouldBroadcastNow ; un
événement qui vise aussi une autre connexion est toujours mis en file. Pour
retrouver l'ancien comportement :
MERCURE_URL="${APP_URL}/.well-known/mercure"
MERCURE_ASYNC=trueLe mode asynchrone exige une url Mercure, car les workers publient en HTTP. La
même contribution (Kévin Dunglas) corrige les commandes Artisan qui plantaient
avec BROADCAST_CONNECTION=mercure quand aucune url n'est définie et que la
fonction FrankenPHP mercure_publish() n'est pas disponible.
Échappement dans les mails Markdown. Un texte placé dans le libellé d'un lien Markdown pouvait échapper le crochet fermant avec une barre oblique inverse et changer la cible du lien. Les barres sont maintenant échappées avec les crochets (correctif de Stephen Rees-Carter).
Les ajouts
Builders
Rule::pour chaque règle de validation qui n'avait qu'une syntaxe en chaîne :required_with,accepted_if,url,uuid,distinct… Les règles sans paramètre (Rule::required(),Rule::nullable()) renvoient la chaîne ; celles à paramètres renvoient un objet qui les passe au validateur sous forme de tableau, si bien qu'une valeur contenant une virgule n'est plus coupée en deux.PHP $request->validate([ 'phone' => [Rule::requiredWithout('email')], 'website' => ['nullable', Rule::url()->protocols(['https'])], 'device_id' => [Rule::uuid()->version(4)], 'tags.*' => [Rule::distinct()->ignoreCase()], 'password' => ['required', Rule::confirmed()], ]);DB::olap()pour PlanetScale et les bases Vitess. La charge OLTP par défaut y est plafonnée à 100 000 lignes par requête ; la méthode bascule sur la charge OLAP le temps d'un callback, sur les connexions de lecture et d'écriture. Hors Vitess, elle exécute simplement le callback, donc le même code tourne contre un MySQL local.PHP $revenue = DB::olap(fn () => Order::query() ->selectRaw('customer_id, sum(total) as revenue') ->where('created_at', '>=', now()->subYears(3)) ->groupBy('customer_id') ->get());Connexions sticky et files d'attente. Avec
stickyactivé, une écriture envoie les lectures suivantes vers la connexion d'écriture. Un worker étant un processus long, un seul job qui écrit peut y envoyer les lectures de tous les jobs suivants. Un indicateur, désactivé par défaut, réinitialise l'état avant chaque job :PHP use Illuminate\Queue\Worker; // AppServiceProvider::boot() Worker::$flushStickyConnections = true;Il est opt-in parce qu'un job peut dépendre de ce qu'un précédent, dans le même worker, a écrit.
Mailables en file :
#[DeleteWhenMissingModels]et#[FailOnTimeout]sont enfin respectés. Si la commande est supprimée avant l'envoi, le job l'est aussi au lieu d'échouer enModelNotFoundException; un mail qui dépasse le délai est marqué échoué au lieu d'être retenté, et peut-être envoyé deux fois.
Source : Rule Builders for Every Validation Rule in Laravel 13.36, Laravel News, 14 octobre 2026.