Laravel 12.49 : nouvelle méthode hasSole() et support des subqueries pour whereBetweenColumns

L
Laravel Actu
4 min

La version 12.49 de Laravel, publiée le 28 janvier 2026, enrichit l’API des collections avec hasSole() et améliore le query builder. Ces ajouts simplifient des patterns courants tout en réduisant la verbosité du code.

La méthode hasSole() sur les collections

Jusqu’à présent, vérifier qu’une collection contenait exactement un élément nécessitait containsOneItem() ou count() === 1. La nouvelle méthode hasSole() offre une syntaxe plus concise et supporte les mêmes signatures de filtrage que sole().

Utilisation basique

<?php

use Illuminate\Support\Collection;

$users = collect([
    ['name' => 'Alice', 'active' => true],
    ['name' => 'Bob', 'active' => false],
]);

// Vérifie si la collection contient exactement un élément
$users->hasSole(); // false (2 éléments)

// Avec une collection d'un seul élément
collect(['unique'])->hasSole(); // true

Filtrage avec callback

La méthode accepte un callback pour filtrer les éléments avant la vérification :

<?php

$orders = collect([
    ['id' => 1, 'status' => 'pending'],
    ['id' => 2, 'status' => 'completed'],
    ['id' => 3, 'status' => 'completed'],
]);

// Vérifie s'il n'y a qu'une seule commande en attente
$hasOnePending = $orders->hasSole(
    fn ($order) => $order['status'] === 'pending'
); // true

// Vérifie s'il n'y a qu'une seule commande complétée
$hasOneCompleted = $orders->hasSole(
    fn ($order) => $order['status'] === 'completed'
); // false (2 commandes)

Syntaxe avec opérateurs

Comme sole(), la méthode supporte la syntaxe clé/valeur et les opérateurs :

<?php

$products = collect([
    ['name' => 'Laptop', 'price' => 999, 'category' => 'tech'],
    ['name' => 'Mouse', 'price' => 29, 'category' => 'tech'],
    ['name' => 'Book', 'price' => 15, 'category' => 'books'],
]);

// Syntaxe clé/valeur
$products->hasSole('category', 'books'); // true
$products->hasSole('category', 'tech');  // false

// Syntaxe avec opérateur
$products->hasSole('price', '>=', 500); // true (seul le Laptop)
$products->hasSole('price', '<', 100);  // false (Mouse et Book)

Dépréciation : la méthode containsOneItem() est désormais dépréciée et délègue vers hasSole(). Elle sera supprimée dans Laravel 13.

Support des subqueries dans whereBetweenColumns

Le query builder accepte maintenant des subqueries comme premier argument de whereBetweenColumns(). Cette fonctionnalité permet des requêtes complexes tout en conservant une syntaxe fluide.

Cas d’usage : validation de plages temporelles

<?php

use Illuminate\Support\Facades\DB;

// Trouve les réservations où la date calculée tombe entre les colonnes
$subquery = DB::table('settings')
    ->select('computed_date')
    ->where('key', 'target_date')
    ->limit(1);

$reservations = DB::table('reservations')
    ->whereBetweenColumns($subquery, ['start_date', 'end_date'])
    ->get();

La requête SQL générée :

SELECT * FROM reservations 
WHERE (SELECT computed_date FROM settings WHERE key = 'target_date' LIMIT 1) 
BETWEEN start_date AND end_date

Avec Eloquent Builder

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;

class Event extends Model
{
    public function scopeActiveAtTimestamp(Builder $query, $timestamp): Builder
    {
        // La subquery peut être un Builder Eloquent
        $timestampQuery = self::query()
            ->selectRaw('?', [$timestamp])
            ->limit(1);

        return $query->whereBetweenColumns(
            $timestampQuery,
            ['starts_at', 'ends_at']
        );
    }
}

// Utilisation
$activeEvents = Event::activeAtTimestamp(now())->get();

Méthode preserveKeys sur AnonymousResourceCollection

Les collections de ressources anonymes supportent maintenant la préservation des clés via une méthode fluide :

<?php

namespace App\Http\Controllers;

use App\Http\Resources\UserResource;
use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    public function index(Request $request)
    {
        // Les clés du tableau associatif sont préservées
        $users = User::all()->keyBy('id');

        return UserResource::collection($users)
            ->preserveKeys(); // Conserve les IDs comme clés
    }
}

Avant cette version, il fallait définir la propriété $preserveKeys sur la classe Resource.

Support étendu des enums

Laravel 12.49 étend le support des enums PHP dans plusieurs composants :

Cache avec enums

<?php

enum CacheKey: string
{
    case UserProfile = 'user_profile';
    case Settings = 'app_settings';
}

// Cache::flexible() accepte les enums
Cache::flexible(
    CacheKey::UserProfile,
    [5, 10], // TTL en secondes
    fn () => User::find(1)
);

// withoutOverlapping() également
Cache::lock(CacheKey::Settings)->withoutOverlapping(
    fn () => updateSettings()
);

Session avec enums

<?php

enum FlashMessage: string
{
    case Success = 'flash_success';
    case Error = 'flash_error';
}

// Session::now() et Session::flash() acceptent les enums
session()->flash(FlashMessage::Success, 'Opération réussie');
session()->now(FlashMessage::Error, 'Une erreur est survenue');

// Récupération
$message = session(FlashMessage::Success->value);

Autres améliorations notables

Option datetime pour la commande down

L’option --retry de la commande down accepte maintenant des valeurs datetime :

# Maintenance jusqu'à une heure précise
php artisan down --retry="2026-01-28 15:00:00"

# Avec un format relatif
php artisan down --retry="+2 hours"

QueueFake::assertPushedTimes rendu public

La méthode assertPushedTimes() est désormais publique, facilitant les tests :

<?php

use Illuminate\Support\Facades\Queue;
use App\Jobs\ProcessOrder;

Queue::fake();

// Dispatch multiple jobs
ProcessOrder::dispatch(1);
ProcessOrder::dispatch(2);
ProcessOrder::dispatch(3);

// Assertion directe sur le nombre de dispatch
Queue::assertPushedTimes(ProcessOrder::class, 3);

Corrections de bugs

  • Memory leak dans Arr::dot() : correction d’une fuite mémoire lors du traitement de tableaux volumineux
  • Str::afterLast() multibyte-safe : gestion correcte des caractères UTF-8
  • Deadlock ignoré sur DatabaseLock::release() : évite les exceptions lors de la libération de verrous en cas de deadlock

Points d’attention

  • La méthode containsOneItem() est dépréciée. Migrez vers hasSole() avant Laravel 13
  • Les nouvelles fonctionnalités de query builder nécessitent des tests approfondis sur vos requêtes existantes
  • Le support des enums améliore la type-safety mais requiert PHP 8.1+

Mise à jour

Pour bénéficier de ces nouveautés :

composer update laravel/framework

Vérifiez votre version :

php artisan --version
# Laravel Framework 12.49.0

Ressources

À propos de Laravel Actu

Développeur passionné par Laravel et son écosystème.

Voir tous les articles
Partager :

Ne manquez aucune actualité Laravel

Recevez les meilleurs articles et tutoriels directement dans votre boîte mail.

Pas de spam. Désinscription possible à tout moment.