Laravel 12.51.0 додає afterSending callbacks, Validator-методи whenFails і whenPasses та timeout() для MySQL

Перекладено ШІ 1 Laravel News 02 червня, 2026

Laravel 12.51.0 приносить кілька практичних оновлень: afterSending() для сповіщень, whenFails()/whenPasses() у валідаторі, timeout() для MySQL, відкладені замикання у firstOrCreate та низку інших покращень і виправлень. Читайте статтю, щоб побачити приклади використання та дізнатися, як ці зміни спростять вашу роботу з кодом.

Дата випуску: 10 лютого 2026
Версія Laravel: 12.51.0

Короткий огляд

Laravel v12.51.0 додає колбеки afterSending() у Notification, флюентні методи whenFails() та whenPasses() у Validator, метод timeout() для MySQL query builder, а також підтримку замикань у firstOrCreate і createOrFirst для лінивої оцінки значень. У релізі з'явився подія BatchCancelled, підтримка Eloquent builder як підзапитів в update-запитах і метод withoutHeader() у Response.

Головні нововведення:

  • Колбеки afterSending() у Notification
  • Методи whenFails() і whenPasses() у Validator
  • Метод timeout() у MySQL query builder
  • Підтримка замикань у firstOrCreate / createOrFirst
  • Подія BatchCancelled
  • Eloquent builders як підзапити в update-запитах
  • withoutHeader() у Response
  • Покращення тестування батчів та ізоляція кешу для паралельних тестів
  • Безліч виправлень багів та покращень типізації

Що нового

Notification — виклики afterSending()

Класи Notification тепер можуть визначати метод afterSending, який виконується після відправлення сповіщення на кожному каналі. Це зручний спосіб виконувати логіку після відправлення — наприклад оновити модель або кинути подію — без реєстрації окремого слухача NotificationSent:

class BookingNotification extends Notification
{
    public function __construct(public Booking $booking) {}
 
    public function via(): array
    {
        return ['mail'];
    }
 
    public function toMail(): MailMessage
    {
        // ...
    }
 
    public function afterSending($notifiable, $channel, $response)
    {
        $this->booking->update(['notified_at' => now()]);
    }
}

Метод отримує інстанс notifiable, назву каналу та відповідь каналу — цього достатньо для подальших дій.

Pull Request: #58654

Validator — методи whenFails() та whenPasses()

Validator отримав флюентні методи whenFails() та whenPasses() для обробки результатів валідації. Це особливо корисно поза HTTP-циклoм — наприклад в Artisan-командах або queue job:

public function someMethod($file)
{
    Validator::make(
        ['file' => $file],
        ['file' => 'required|image|dimensions:min_width=100,min_height=200']
    )->whenFails(function () {
        throw new InvalidArgumentException('Provided file is invalid');
    });
}

Ці методи — альтернатива ручній перевірці $validator->fails() або обгортанню в try/catch.

Pull Request: #58655

MySQL query builder — метод timeout()

Додано метод timeout() у query builder, який встановлює таймаут виконання запиту для MySQL через optimizer hint MAX_EXECUTION_TIME:

Student::query()
    ->where('email', 'like', '%text%')
    ->timeout(60)
    ->get();
 
// Generates: select /*+ MAX_EXECUTION_TIME(60000) */ * from `students` where `email` like ?

Можна також застосувати його як дефолт через глобальний scope:

use Illuminate\Database\Eloquent\Attributes\ScopedBy;
 
class TimeoutScope implements Scope
{
    public function apply(Builder $builder, Model $model)
    {
        $builder->timeout(60);
    }
}
 
#[ScopedBy([TimeoutScope::class])]
class User extends Model
{
    // ...
}

Функція специфічна для MySQL і приймає значення таймауту в секундах.

Pull Request: #58644

Замикання в firstOrCreate і createOrFirst

Методи firstOrCreate та createOrFirst тепер приймають closures для параметра $values, що дозволяє відкладено обчислювати дорогі операції:

// Before — expensive operation always runs
$location = Location::query()->firstWhere('address', $address);
 
if ($location) {
    return $location;
}
 
return Location::create([
    'address' => $address,
    'coordinates' => Geocoder::resolve($address),
]);
 
// After — geocoding only runs when a new record is needed
$location = Location::firstOrCreate(
    ['address' => $address],
    fn () => ['coordinates' => Geocoder::resolve($address)],
);

Якщо запис уже існує, замикання не виконується — це запобігає зайвим API-запитам чи обчисленням.

Pull Request: #58639

Подія BatchCancelled

Додано подію BatchCancelled, яка глобально спрацьовує при скасуванні батчу — автоматично через помилку в job або при ручному скасуванні. Це дає змогу відслідковувати скасування батчів без опитування:

use Illuminate\Bus\Events\BatchCancelled;
use Illuminate\Support\Facades\Event;
 
Event::listen(BatchCancelled::class, function (BatchCancelled $event) {
    Log::warning("Batch {$event->batch->id} was cancelled.");
});

Pull Request: #58627

Eloquent builders як підзапити в update

Eloquent builders і relations тепер можна передавати напряму як підзапити в update-викликах без конвертації в base query:

// Before
FooModel::where('...')->update([
    'bar_id' => BarModel::where('...')->toBase()->select('id'),
]);
 
// After
FooModel::where('...')->update([
    'bar_id' => BarModel::where('...')->select('id'),
]);

Виклик ->toBase() більше не потрібен при використанні Eloquent builder як значення підзапиту.

Pull Request: #58692

withoutHeader() у Response

Додано метод withoutHeader() для видалення заголовків з HTTP-відповіді — симетрично до існуючого withoutCookie():

// Remove a single header
return response($content)->withoutHeader('X-Debug');
 
// Remove multiple headers
return response($content)->withoutHeader(['X-Debug', 'X-Powered-By', 'Server']);

Pull Request: #58671

Виправлення багів і покращення

Тестування:

  • assertJobs у PendingBatchFake для перевірок job у батчі (#58606)
  • Bus::assertBatched() з підтримкою масивів (#58659)
  • viewData() без ключа повертає всі дані view у TestResponse (#58700)
  • Ізоляція префікса кешу для паралельних тестів через трейд TestCaches (#58691)

HTTP Client:

  • throwIfStatus/throwUnlessStatus тепер працюють для всіх статусів, включаючи 2xx і 3xx (#58724)

Database & Eloquent:

  • Метод orderByPivotDesc() для спадного сортування pivot-колонки (#58720)
  • whereBetween приймає DatePeriod і коректно обробляє відсутні кінцеві дати (#58687)
  • Підтримка SSL cert/key для дампів та завантаження схем MySQL (#58690)
  • Виправлення початкового значення sequence у Postgres для кастомних схем/з'єднань (#58199)
  • Коригування freshTimestamp для SQL Server (#58614)
  • Виправлення підрахунку батчів, коли deleteWhenMissingModels пропускає відсутні моделі (#58541)

Strings & Helpers:

  • Stringable::deduplicate() приймає масив символів (#58649)
  • Виправлено Str::substrReplace для граничних випадків з від'ємним offset або length (#58634)
  • Виправлено Str::isUrl(), яке повертало false для односимвольних доменів (#58686)
  • Заміна substr на mb_substr для кодування user agent (#58703)

Queue & Middleware:

  • Можливість вказати Redis-підключення в Redis-based queue middleware (#58656)
  • Виправлено, що Queue::fake() не звільняв унікальні блокування job між тестами (#58718)

Translation & Localization:

  • Усунено дублювання перевірок локалі в Lang::get(), коли локаль збігається з fallback (#58626)
  • Виправлено regex у trans_choice, щоб дозволити від'ємні діапазони (#58648)

Framework & Internals:

  • Відновлення оригінальних биндів dispatcher після precognitive request — фікс для Octane і Pest (#58716)
  • Обробка бінарних даних у Js::encode() debug renderer (#58618)
  • Додав ArrayObject props до AsEncryptedArrayObject щоб відповідати AsArrayObject (#58619)
  • Виправлено поп-ін сторінки винятків для неосновних фреймів (#58698)
  • Вирівнювання ASCII SVG символів Laravel (#58702, #58719)
  • Додано депрекацію до Request::get() (#58635)
  • Оновлено завдання reload для включення schedule:interruption (#58637)

Посилання

Популярні

Інше, що варто прочитати

17 Оновлено 01 червня, 2026

Налаштування Xdebug з Docker та PHP 8.4 всього за одну хвилину

Встановлення Xdebug може бути складним завданням, але в цій статті ми розкриємо, як швидко та просто налаштувати його за допомогою Docker на прикладі Laravel. Дочитайте до кінця, щоб дізнатися, як за кілька хвилин зробити Xdebug вашим надійним помічником у розробці

17 Оновлено 01 червня, 2026

Обробка геопросторових даних за допомогою Laravel Magellan

Ви готові відкрити нові горизонти у роботі з геопросторовими даними в Laravel? Дізнайтеся, як за допомогою PostGIS та пакету Laravel-Magellan можна легко зберігати, запитувати та маніпулювати інформацією про розташування, перетворюючи ваші проекти на вражаючі рішення у сфері картографії та геолокації!

173 Оновлено 01 червня, 2026

Використання повнотекстового пошуку в Laravel

Laravel пропонує потужні можливості повнотекстового пошуку за допомогою методів whereFullText та orWhereFullText, що дозволяють здійснювати складні запити до бази даних. Дізнайтеся, як реалізувати ефективний пошук для вашого блогу чи системи управління контентом