Laravel v13.5.0 додає повноцінну підтримку Redis Cluster для драйвера черг та обмежувача паралельності (concurrency limiter). Це розв'язує проблему з помилками CROSSSLOT в AWS ElastiCache Serverless та інших конфігураціях Redis Cluster. Також у релізі: атрибут #[Delay] для Mailables, успадкування Middleware в контролерах, розширена підтримка Enum у менеджерах та низка виправлень.
ConcurrencyLimiter#[Delay] тепер працює для поштових повідомлень (mailables) у черзіupdateOrCreate та firstOrNewCache::handleUnserializableClassUsing() для виявлення пошкоджених значень у кешіShouldBeUniqueUntilProcessing, які вивільняли чужі замки (locks)Раніше при використанні AWS ElastiCache Serverless (Valkey) або будь-якого Redis Cluster черги Laravel та ConcurrencyLimiter могли видавати помилки CROSSSLOT. Lua-скрипти черг працюють із кількома ключами — queues:default, queues:default:reserved та queues:default:notify. Оскільки вони потрапляли у різні слоти кластера, Redis Cluster забороняв виконання такої операції в межах однієї команди.
Тепер Laravel автоматично обгортає назви черг у хеш-теги Redis, якщо використовується кластерне з’єднання. Це гарантує, що всі пов’язані ключі потраплять в один слот:
queues:{default} → слот для "default"
queues:{default}:delayed → слот для "default"
queues:{default}:reserved → слот для "default"
queues:{default}:notify → слот для "default"
Різні черги (наприклад, {emails} та {notifications}) продовжують природно розподілятися по кластеру. Публічний метод getQueue() залишився без змін, тому сторонні інтеграції бачать назви черг у звичному форматі. Для користувачів без кластерів нічого не змінилося.
Аналогічне рішення впроваджено для ConcurrencyLimiter — ключі тепер обгортаються у хеш-теги, що запобігає конфліктам слотів у Lua-скриптах.
Для phpredis 5.3.2+ конектор кластера отримав підтримку ACL-авторизації та нові опції: max_retries, backoff_algorithm, backoff_base та backoff_cap. Це покращує сумісність із динамічним масштабуванням ElastiCache Serverless.
Pull Request: #59533 від @timmylindh
Атрибут #[Delay], який з'явився у версії v13.4.0 для завдань та подій, тепер підтримується і в Mailables. Раніше поштові класи ігнорували цей атрибут, використовуючи лише властивість $delay.
use Illuminate\Queue\Attributes\Delay;
#[Delay(30)]
class WelcomeEmail extends Mailable implements ShouldQueue
{
// Тепер коректно затримується на 30 секунд у черзі
}
Властивість $delay, як і раніше, має пріоритет, якщо вона встановлена явно.
Pull Request: #59580 від @sumaiazaman
Атрибут #[Middleware] на базовому контролері тепер успадковується дочірніми класами. Раніше розробникам доводилося дублювати атрибути в кожному класі-нащадку.
use Illuminate\Routing\Attributes\Middleware;
#[Middleware('auth')]
#[Middleware('log:api')]
abstract class AdminBaseController extends Controller
{
// Загальна логіка адмінки
}
class AdminController extends AdminBaseController
{
public function index()
{
// Успадковує мідлвари 'auth' та 'log:api' від батька
}
}
Pull Request: #59597 від @niduranga
Підтримку Enum додано до кількох менеджерів, де її бракувало:
CacheManager — методи store(), driver(), memo(), forgetDriver(), purge() та setDefaultDriver() тепер приймають UnitEnum:
enum CacheStore: string
{
case Redis = 'redis';
case Array = 'array';
}
Cache::store(CacheStore::Redis)->put('key', 'value');
MailManager — методи mailer(), driver() та purge() підтримують Enum.
AuthManager — guard(), shouldUse() та setDefaultDriver() також отримали підтримку Enum.
Крім того, підтримка Enum з'явилася в базовому методі Manager::driver(), що поширює цей паттерн на всі класи, які від нього успадковуються.
Pull Requests: #59637, #59645, #59646, #59659
Методи updateOrCreate та firstOrNew тепер дозволяють передавати Closure як аргумент $values. Це завершує впровадження механізму «лінивих» обчислень для цих методів. Це корисно для виконання ресурсномістких операцій (наприклад, запитів до сторонніх API), які мають запускатися лише тоді, коли запис дійсно потрібно створити чи оновити.
$location = Location::updateOrCreate(
['address' => $address],
fn () => ['coordinates' => Geocoder::resolve($address)],
);
Pull Request: #59647 від @yousefkadah
Новий хук Cache::handleUnserializableClassUsing() дозволяє зареєструвати callback, який спрацює, якщо значення з кешу десеріалізується як __PHP_Incomplete_Class. Це часто трапляється, коли використовується список дозволених класів (serializable_classes), але потрібний клас у ньому відсутній.
Cache::handleUnserializableClassUsing(function (string $key, ?string $class): void {
if (app()->isProduction()) {
Log::warning("Cache hit [{$key}] повернув клас, що не підлягає серіалізації: [{$class}]");
return;
}
throw new RuntimeException("Помилка десеріалізації для ключа [{$key}], клас: [{$class}]");
});
Pull Request: #59630 від @jackbayliss
Queue:
ShouldBeUniqueUntilProcessing вивільняли замки, які їм не належать.Redis:
Auth:
redirectUsersTo() перезаписував callback redirectGuestsTo().NotPwnedVerifier.Testing:
TestCase::withoutBootingFramework() тепер кешується (memoization) для уникнення зайвих обчислень.References
Чи стикалися ви з помилкою «SQLSTATE[HY000] [2002] Connection refused» під час налаштування GitHub Actions для вашого додатку на Laravel? У нашій статті ми розглянемо три поширені причини цієї помилки та надамо рішення для їх усунення. Читайте далі, щоб дізнатися, як ваш CI/CD потік може працювати бездоганно!
Ви готові відкрити нові горизонти у роботі з геопросторовими даними в Laravel? Дізнайтеся, як за допомогою PostGIS та пакету Laravel-Magellan можна легко зберігати, запитувати та маніпулювати інформацією про розташування, перетворюючи ваші проекти на вражаючі рішення у сфері картографії та геолокації!
Laravel Livewire випустив нову версію 3.6, яка приносить з собою цікаві HTML-директиви для управління видимістю DOM-елементів і JavaScript-діями. Досліджуйте нові можливості Livewire, що допоможуть вам створити ще більш інтерактивні користувацькі інтерфейси!