Дата випуску: 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() у NotificationwhenFails() і whenPasses() у Validatortimeout() у MySQL query builderfirstOrCreate / createOrFirstBatchCancelledwithoutHeader() у ResponseКласи 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() для обробки результатів валідації. Це особливо корисно поза 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
Додано метод 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 тепер приймають 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, яка глобально спрацьовує при скасуванні батчу — автоматично через помилку в 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 і 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() для видалення заголовків з 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)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:
Queue::fake() не звільняв унікальні блокування job між тестами (#58718)Translation & Localization:
Lang::get(), коли локаль збігається з fallback (#58626)trans_choice, щоб дозволити від'ємні діапазони (#58648)Framework & Internals:
Js::encode() debug renderer (#58618)AsEncryptedArrayObject щоб відповідати AsArrayObject (#58619)Request::get() (#58635)schedule:interruption (#58637)Встановлення Xdebug може бути складним завданням, але в цій статті ми розкриємо, як швидко та просто налаштувати його за допомогою Docker на прикладі Laravel. Дочитайте до кінця, щоб дізнатися, як за кілька хвилин зробити Xdebug вашим надійним помічником у розробці
Ви готові відкрити нові горизонти у роботі з геопросторовими даними в Laravel? Дізнайтеся, як за допомогою PostGIS та пакету Laravel-Magellan можна легко зберігати, запитувати та маніпулювати інформацією про розташування, перетворюючи ваші проекти на вражаючі рішення у сфері картографії та геолокації!
Laravel пропонує потужні можливості повнотекстового пошуку за допомогою методів whereFullText та orWhereFullText, що дозволяють здійснювати складні запити до бази даних. Дізнайтеся, як реалізувати ефективний пошук для вашого блогу чи системи управління контентом