Laravel 12.52 : Factory makeMany(), uploads locaux temporaires et écritures atomiques Blade
Laravel 12.52 enrichit le framework avec une poignée de nouveautés très concrètes : une méthode makeMany() pour les factories, le support des URLs d’upload temporaires en local, et un correctif critique de race condition dans le compilateur Blade. Une release tournée vers la productivité quotidienne des développeurs.
Contexte de la release
Sortie le 17 février 2026, la version 12.52.0 est une release mineure du framework Laravel. Elle compile plus de 40 pull requests, mêlant nouvelles fonctionnalités, corrections de bugs et améliorations de typage. Les contributions viennent notamment de @jackbayliss, @mnapoli, @cyppe et @ziadoz.
Pour mettre à jour :
composer update laravel/framework
Aucun breaking change n’est signalé pour les applications standards.
Factory : la méthode makeMany()
Jusqu’ici, createMany() permettait de créer plusieurs modèles en base de données en un seul appel. Mais pour générer plusieurs instances sans les persister, il fallait enchaîner count() et make(), ou passer par forEachSequence(). La méthode makeMany() comble ce manque.
use App\Models\Tag;
// Avant : syntaxe verbeuse pour créer des instances en mémoire
$tags = Tag::factory()
->forEachSequence(
['name' => 'PHP'],
['name' => 'Laravel'],
['name' => 'Testing'],
)
->make();
// Après : syntaxe directe avec makeMany()
$tags = Tag::factory()->makeMany([
['name' => 'PHP'],
['name' => 'Laravel'],
['name' => 'Testing'],
]);
// Ou simplement pour N instances avec les valeurs par défaut
$users = User::factory()->makeMany(5);
Cette méthode retourne une Collection d’instances de modèles non sauvegardées. Très utile pour les tests unitaires où l’accès à la base de données n’est pas nécessaire, ce qui accélère considérablement l’exécution des suites de tests.
Désactiver les callbacks de factory à la demande
Deux nouveaux helpers accompagnent makeMany() : withoutAfterMaking() et withoutAfterCreating(). Ils permettent de désactiver ponctuellement les callbacks afterMaking et afterCreating définis dans vos factories.
use App\Models\User;
// Ignorer les callbacks afterMaking (ex: attribution de rôle automatique)
$user = User::factory()
->withoutAfterMaking()
->make();
// Ignorer les callbacks afterCreating (ex: envoi d'email de bienvenue)
$user = User::factory()
->withoutAfterCreating()
->create();
Ces helpers sont précieux quand une factory déclenche des effets de bord — création de relations, dispatch d’événements — qui ne sont pas pertinents pour le test en cours. Vous gardez vos factories riches en logique métier sans compromettre la vitesse de tests ciblés.
URLs d’upload temporaires pour le filesystem local
La méthode temporaryUploadUrl() était réservée aux drivers cloud comme S3. Cette limitation forçait les développeurs à configurer un service externe (S3, MinIO) même en développement local. Laravel 12.52 étend cette fonctionnalité au driver local.
use Illuminate\Support\Facades\Storage;
// Générer une URL d'upload temporaire signée sur le disque local
[$url, $headers] = Storage::disk('local')->temporaryUploadUrl(
'uploads/avatar.jpg',
now()->addMinutes(30)
);
// Le client peut ensuite faire un PUT sur cette URL
// L'URL est signée et expire après 30 minutes
Le mécanisme repose sur des URLs signées, ce qui garantit la sécurité : une URL de téléchargement ne peut pas être utilisée pour uploader, et inversement. Un point soulevé pendant la review de la PR (#58499) a conduit à l’ajout de cette protection avant le merge.
Pour le développement local, vous pouvez aussi personnaliser la logique via buildTemporaryUploadUrlsUsing() — exactement comme pour temporaryUrl().
Écritures atomiques dans le compilateur Blade
C’est probablement le correctif le plus impactant de cette release. Le compilateur Blade utilisait file_put_contents() pour écrire les vues compilées en cache. Sur des serveurs multi-threads comme FrankenPHP, plusieurs workers pouvaient compiler la même vue simultanément. Résultat : file_put_contents() tronquait le fichier à 0 octets avant d’écrire, et un autre thread effectuant un include pendant cette fenêtre récupérait un contenu vide.
// Avant (dans BladeCompiler::compile())
// Risque de race condition en environnement multi-thread
$this->files->put($compiledPath, $contents);
// Après : écriture atomique via un fichier temporaire + rename()
// rename() est atomique sur les systèmes POSIX
$this->files->replace($compiledPath, $contents);
La méthode Filesystem::replace() écrit d’abord dans un fichier temporaire, puis effectue un rename() — opération atomique sur les systèmes POSIX. Tout lecteur concurrent voit soit l’ancien contenu complet, soit le nouveau, jamais un fichier vide ou corrompu.
Ce bug se manifestait typiquement par une RootTagMissingFromViewException de Livewire juste après un déploiement, sur les toutes premières requêtes touchant un nouveau container.
Autres améliorations notables
Correction du délai sur Mailable::later()
Mailable::later() ne transmettait pas correctement le délai au job SendQueuedMailable. C’est corrigé, et de nouvelles assertions permettent de vérifier le délai dans vos tests :
use Illuminate\Support\Facades\Mail;
use App\Mail\WelcomeMail;
Mail::fake();
// Envoyer un mailable avec un délai de 10 minutes
Mail::to('user@example.com')
->later(now()->addMinutes(10), new WelcomeMail());
// Vérifier que le mailable a bien été mis en queue avec le bon délai
Mail::assertQueued(WelcomeMail::class, function ($mail) {
return $mail->delay->equalTo(now()->addMinutes(10));
});
Expressions string pour selectExpression()
selectExpression() accepte désormais des chaînes brutes en plus des objets Expression, ce qui réduit le boilerplate :
use Illuminate\Support\Facades\DB;
// Avant : passage par DB::raw() obligatoire
DB::table('orders')->selectExpression(DB::raw('SUM(total) as revenue'));
// Après : chaîne acceptée directement
DB::table('orders')->selectExpression('SUM(total) as revenue');
Autres corrections
LazyCollection::random()supporte maintenant le paramètre$preserveKeyspour conserver les clés originales- Les closures et fonctions standalone s’affichent correctement dans les traces d’exception
- Les callbacks
deferne sont plus supprimés lors de l’utilisation de la queuesync Batch::progress()retourne désormais unintau lieu d’unfloat- Correction MySQL : utilisation de
--ssl-mode=DISABLEDpour les clients modernes - Option de cache parallèle : possibilité de désactiver le préfixe de cache isolé pour les tests parallèles
Points d’attention
- Pas de breaking changes pour les applications standard
- Le revert des vérifications de précision SQL Server restaure le comportement antérieur à v12.51.0 — vérifiez vos migrations SQL Server si vous vous appuyiez sur ce comportement
- Le backport des changements
withMiddlewaredepuis la branche 13.x peut nécessiter une vérification si vous utilisez des middlewares personnalisés de manière avancée - Si vous utilisez FrankenPHP ou un serveur multi-thread, la correction atomique Blade est une raison suffisante pour mettre à jour
Conclusion
Laravel 12.52 est une release qui mise sur la qualité de vie du développeur. makeMany() simplifie les tests, temporaryUploadUrl() élimine le besoin de services cloud en local, et la correction atomique Blade résout un bug insidieux en production multi-thread. Le tout sans aucun breaking change — la mise à jour est un simple composer update.
Ressources
À propos de Laravel Actu
Développeur passionné par Laravel et son écosystème.
Voir tous les articles