Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Події
Інше
Про нас
Новини 20 серпня 2026

Файлові системи з автопросуванням та відкладені слухачі у Laravel 13.26

Команда Laravel випустила версію 13.26.0 18 серпня 2026 року. Реліз додає драйвер файлової системи read-through, який шарує основний диск поверх резервного та просуває файли при першому читанні, можливість відкладання (debouncing) для слухачів подій у черзі, метод Queue::forward() для перенаправлення черг без змін у класах завдань, а також низку покращень роботи з процесами, Eloquent та Redis.

Файлові системи з автопросуванням (Read-Through)

Новий драйвер read-through об'єднує два існуючі диски в один. При читанні спочатку перевіряється основний диск, а при його відсутності відбувається звернення до резервного з автоматичним копіюванням файлу на основний диск. Таким чином основний диск поступово заповнюється лише тими файлами, які реально запитуються. Операції запису, видалення та отримання списку директорій виконуються лише на основному диску:

'assets' => [
    'driver' => 'read-through',
    'primary' => 'r2',
    'fallback' => 'legacy-s3',
],

Диски можна вказувати як назви (як у прикладі вище) або визначати безпосередньо як масиви конфігурації. Опція copy => false дозволяє віддавати файли з резервного диску без просування на основний, що підходить для середовищ розробки, які працюють з продакшн-файлами. Помилки просування за замовчуванням ігноруються, щоб операція читання ніколи не провалювалася через невдале копіювання. Встановіть throw_on_promotion_failure => true, щоб викидати виключення при помилках.

Функціональність додана @taylorotwell у /#61140, опція без копіювання - @jimbojsb у /#61155.

Відкладені слухачі подій у черзі

Атрибут #[DebounceFor], який додав можливість відкладання для завдань у черзі в Laravel 13.6, тепер працює і зі слухачами подій у черзі. Коли одна й та сама подія спрацьовує багаторазово, виконується лише останнє відправлення в межах вікна:

use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\Attributes\DebounceFor;

#[DebounceFor(30, maxWait: 120)]
class UpdateProductSearchIndex implements ShouldQueue
{
    public function debounceId(ProductUpdated $event): string
    {
        return (string) $event->product->getKey();
    }
    
    public function handle(ProductUpdated $event): void
    {
        // переіндексація виконається один раз із найновішим станом
    }
}

Метод debounceId() обмежує вікно для кожного окремого ресурсу, параметр maxWait встановлює максимальний час, протягом якого активний потік подій може відкладати виконання роботи. Відкладання застосовується лише до цього слухача, тому інші слухачі тієї ж події виконуються кожного разу. Відкладений слухач не може одночасно реалізовувати ShouldBeUnique - диспетчер викине LogicException, оскільки унікальність зберігає перше відправлення, а відкладання - останнє.

Додано @stevebauman у /#61169.

Метод Queue::forward()

Метод Queue::forward() перенаправляє все, що відправляється до певної черги, на іншу чергу, інше з'єднання або обидва варіанти одночасно. Це робиться в одному місці в сервіс-провайдері без редагування класів завдань або місць їхнього відправлення:

use Illuminate\Support\Facades\Queue;

Queue::forward('reports', 'reports.fifo', 'cloud'); // перейменування і зміна з'єднання
Queue::forward('payments', connection: 'cloud');    // збереження назви, зміна з'єднання
Queue::forward('updates', 'notifications');         // перейменування на тому ж з'єднанні
Queue::forward([
    'reports' => 'reports.fifo',
    'emails' => 'emails.fifo',
], connection: 'cloud');

Перенаправлення застосовуються через той самий механізм, що й Queue::route(), тому вони працюють незалежно від способу потрапляння завдання до черги. Додано @jackbayliss у /#61188.

Покращення роботи з процесами

Три нові можливості фасаду Process, усі від @xurshudyan. Пули процесів та їхні результати тепер ітеровані (/#61184). Раніше foreach над ProcessPoolResults ітерував публічні властивості, яких немає, тому цикл для перевірки кодів виходу мовчки нічого не перевіряв. Обидва класи тепер реалізують IteratorAggregate.

Тайм-аут простою тепер викидає власний виняток ProcessIdleTimedOutException (/#61182). Два тайм-аути означають протилежні речі - завислий процес проти повільного, але обидва раніше викидали ProcessTimedOutException:

try {
    Process::timeout(600)->idleTimeout(30)->run('./deploy.sh');
} catch (ProcessIdleTimedOutException $e) {
    // немає виводу протягом 30 секунд: вбити і сповістити
} catch (ProcessTimedOutException $e) {
    // досі виробляє вивід, просто повільний: повторити з більшим часом
}

Фейк Process отримав допоміжні методи для перевірок (/#61193, /#61197): assertRanCount(2) перевіряє кількість запущених процесів, assertRanInOrder([...]) перевіряє послідовність, а recorded() фільтрує записані пари процесів та результатів за допомогою callback. Перевірки порядку та кількості приймають як рядкові команди, так і масиви.

Доповнення Eloquent Builder

Методи orWhereKey() та orWhereKeyNot() доповнюють існуючу пару whereKey(), замінюючи fallback orWhereIn('id', ...) у запитах, де потрібна умова за первинним ключем у гілці or (@calebdw, /#61154).

Методи wherePivot() та orWherePivot() приймають closure, яке отримує builder, обмежений до моделі pivot, тому scope, визначені на користувацькому pivot-класі, можна викликати з запиту зв'язку (@calebdw, /#61150):

$project->subscribers()
    ->wherePivot(fn ($query) => $query->active()->notMuted())
    ->get();

Метод inOrderOf() тепер приймає enum у списку значень, відповідно до підтримки enum в інших місцях query builder (@ziadoz, /#61147):

$orders = Order::query()
    ->inOrderOf('status', [Status::Pending, Status::Processing, Status::Shipped])
    ->get();

Зв'язки також отримали аксесор getRelatedClass() (/#61222).

Покращена видимість Queue Worker

Нова подія JobReleased спрацьовує, коли завдання повертається до черги зі свого власного обробника або з middleware, такого як WithoutOverlapping (/#61108). Існуюча подія JobReleasedAfterException покривала лише випадки повернення через виняток, тому повернення через перекриття було невидимим.

Worker тепер також виводять повідомлення, коли черга, яку вони обробляють, призупинена, і знову, коли вона відновлюється (/#61142). З моменту появи API призупинення призупинений worker просто переставав виводити інформацію, що виглядало як зависання. Worker, запущений проти вже призупиненої черги, також повідомляє про це. Обидва внески від @jackbayliss.

Інші виправлення та покращення

  • Тепер підтримується Guzzle 8 поряд із Guzzle 7 (/#60321)
  • Команда db:seed --class=SpecificSeeder показує той самий вивід прогресу RUNNING/DONE, який вкладені seeders вже отримували через Seeder::call() (/#61186)
  • Серія покращень Redis: перевірки призупинених черг більше не виконують читання між слотами на кластерах (/#61139), очищення тегів кешу сканує кожен головний вузол (/#61174) і більше не зациклюється на застарілих тегах (/#61181), невдалий pipeline або транзакція залишає з'єднання придатним (/#61183), клієнт phpredis перебудовується після помилки відповіді кластера (/#61214), деякі команди повторюються при тимчасових збоях (/#61175)
  • Драйвер Cloud queue відкриває managedQueues() (/#61149), події керованих черг просувають вкладені дані на верхній рівень (/#61209), тайм-аути long-poll cloud agent повторюються (/#61177)
  • Метод throwUnless() більше не мовчить у випадках, коли має викидати виняток (/#61217), порядок ключів вводу Request зберігається при об'єднанні файлів (/#61221)
  • Налаштування readonly=false дотримується в конфігурації Microsoft SQL Server (/#61141), одинарні лапки екрануються в атрибутах JSON-шляху Postgres (/#61192), параметри запиту JSON:API у вигляді масивів більше не викликають TypeError (/#61206)
  • Команда pail для розробки реєструється лише коли встановлено Pail (/#61157), artisan dev припиняє постійно пропонувати встановити @laravel/multiplex (/#61167), закріплена версія multiplex видалена (/#61171)
  • Покращення для тестування: помилки сесії зберігають оригінальне повідомлення про провал твердження (/#61201), виправлено проблему повторного використання setTestNow() з now() (/#61190), docblock expectsQuestion() дозволяє масиви відповідей (/#61223)

Примітки щодо оновлення

Для типових застосунків не очікується breaking changes. Два моменти, про які варто знати: слухач із атрибутом #[DebounceFor] тепер викидає LogicException, якщо він також реалізує ShouldBeUnique, а внутрішня логіка whereKey() / whereKeyNot() була консолідована у /#61154, що має значення лише якщо ви розширюєте Eloquent builder і перевизначаєте ці методи. Перегляньте changelog для деталей по кожному PR при оновленні.

6

Читати в документації

Коментарі

Увійдіть, щоб залишити коментар

Будьте першим, хто залишить коментар!

Читайте також

whereBinary()
Новини 28 серпня 2026

whereBinary(): регістрозалежні запити MySQL у Laravel

Laravel 13.27 додає новий метод whereBinary() для точного побайтового порівняння рядків у MySQL. Він вирішує проблему, коли стандартне collation utf8mb4_unicode_ci ігнорує регістр, акценти та пробіли при порівнянні токенів, slug-ів та інших критичних даних.

ToolSearch
Новини 27 серпня 2026

Laravel AI: завантаження інструментів на вимогу з ToolSearch

Laravel AI v0.11.0 додає механізм відкладеного завантаження інструментів агента через ToolSearch. Замість надсилання всіх тридцяти інструментів одразу, провайдер отримує лише пошуковий запис і завантажує повні визначення тільки тоді, коли модель вирішує їх використати.

2

Вакансії за темою

Alliance Digital Нова
Сьогодні

PHP Developer

Middle PHP-розробник для фінтех-продукту. Розробка backend на Laravel з PostgreSQL, RabbitMQ, Redis. Реалізація складної бізнес-логіки кредитування, фінансових операцій, зовнішніх інтеграцій. Вимоги: 3+ років PHP, впевнена робота з Laravel, OOP/SOLID, складна бізнес-логіка, PostgreSQL, черги, тестування, production-mindset.

SendPulse Нова
Сьогодні

Middle+ PHP Developer (with DevOps)

Middle+ PHP Developer з DevOps-експертизою для мультикоманди, що розробляє CRM та освітню платформу. Основна роль: проєктування й реалізація модулів на PHP 8 і Laravel, оптимізація під високе навантаження, розробка інтеграцій. DevOps-компонент: налаштування CI/CD, контейнеризація (Docker/Kubernetes), управління AWS-інфраструктурою. Вимоги: глибока експертиза Laravel, Docker, Kubernetes, Git, технічна англійська.

Jamworks Нова
Вчора

Senior PHP Backend Engineer

Досвідчений бекенд-розробник на PHP/Laravel для проектування та розвитку масштабованих, надійних систем. Робота з архітектурою, базами даних, оптимізацією продуктивності, прийняттям технічних рішень. Вимоги: комерційний досвід з PHP та Laravel, ООП, MySQL, Redis, REST API, асинхронна обробка, Docker, Git/CI/CD, чистий код, дебагінг.

Пакети за темою

Pest

pestphp/pest

Тестовий фреймворк з лаконічним синтаксисом поверх PHPUnit: тести описуються функціями замість класів. Має паралельний запуск, тести архітектури, покриття і мутаційне тестування.

11,667 v5.1.1 2

Laravel Medialibrary

spatie/laravel-medialibrary

Пакет для асоціювання файлів з Eloquent-моделями. Надає зручний інтерфейс для управління медіа-файлами, пов'язаними з вашими моделями бази даних.

6,157 11.23.5 13 7