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

Визначення домінантного кольору та підтримка HEIC у Laravel 13.24

Laravel 13.24 розширює можливості фреймворка з обробки зображень, додаючи визначення домінантного кольору та підтримку форматів HEIC і AVIF. Крім того, реліз включає новий метод modelKeys() для Eloquent query builder, правило валідації array_keys та критичне виправлення продуктивності валідації, яке раніше могло затримувати запит понад хвилину при роботі з великими масивами. Команда Laravel випустила версію 13.24.0 4 серпня 2026 року.

Визначення домінантного кольору в Image API

Перша офіційна Image API тепер може визначати середній колір зображення. Метод dominantColor() зменшує зображення до одного пікселя та повертає його колір у форматі hex-рядка:

use Illuminate\Support\Facades\Image;

$color = Image::fromPath(storage_path('app/photo.jpg'))->dominantColor(); 
// "#8a6f4c"

Це значення можна використовувати як фоновий колір-заповнювач під час завантаження фотографії або для тонування картки за її власним зображенням. Результат мемоїзується для кожного екземпляра зображення, і якщо у pipeline є незавершені трансформації, вони виконуються перед визначенням кольору, тому ви отримуєте колір зображення, яке збираєтеся зберегти, а не оригіналу.

Те саме визначення доступне як значення фону. Передача dominant до методів contain() або rotate() заповнює порожні простір letterbox або кути повороту власним домінантним кольором зображення замість заздалегідь обраного:

Image::fromUpload($request->file('photo'))
    ->contain(1200, 800, background: 'dominant')
    ->store('photos');

Підтримка AVIF та HEIC на вході, вивід у HEIC

Раніше Image API підтримувала вивід AVIF через toAvif(), але відхиляла AVIF-файли на вході. Формати HEIC та HEIF відхилялися в обох напрямках, навіть попри те, що Intervention Image постачається з кодером для них. Фотографії безпосередньо з iPhone мають формат HEIC, тому завантаження доводилося конвертувати ще до потрапляння у фреймворк.

Тепер AVIF, HEIC та HEIF приймаються як вхідні формати, доступні toHeic() та optimize('heic') для виводу, і всі три формати розпізнаються правилом валідації image:

Image::fromPath(storage_path('app/photo.heic'))
    ->usingImagick()
    ->cover(1200, 800)
    ->toAvif()
    ->quality(80)
    ->store('photos');

Обидві зміни базуються на можливостях image pipeline. optimize('heif') та MIME-тип image/heif нормалізуються до HEIC, тому файли зберігаються з канонічним розширенням .heic. Метод Image::extension() також вивчив псевдоніми image/x-avif, image/x-heic та image/heif. Обробка HEIC потребує збірки Imagick з вкомпільованим HEIC-кодеком.

Метод modelKeys() у Eloquent Query Builder

Eloquent-колекції давно мали метод modelKeys(), але отримання того самого масиву безпосередньо з запиту означало самостійне зазначення первинного ключа через pluck('id'). Тепер query builder також має цей метод:

$ids = Post::query()->where('published', true)->modelKeys(); 
// [1, 2, 3]

Він витягує кваліфіковане ім'я ключа з моделі, тому кастомний $primaryKey та з'єднані запити розв'язуються коректно без жорсткого кодування імені стовпця.

Правило валідації array_keys

Rule::array(['sort', 'direction']) вже відхиляє масиви з неочікуваними ключами, але повідомляє про помилку загальним повідомленням "The options field must be an array", яке не каже читачеві, яка саме з двох перевірок провалилася. Нове правило валідації array_keys відповідає лише на питання про ключі і повідомляє про це:

$request->validate([
    'options' => Rule::arrayKeys(['sort', 'direction']),
]);

// або як рядок
$request->validate([
    'options' => 'array_keys:sort,direction',
]);

Для вхідних даних ['sort' => 'name', 'colour' => 'red'] повідомлення про помилку: "The options field must only contain the following keys: sort, direction." Ключі є дозволеними, а не обов'язковими, тому це обмежує те, що може з'явитися, а не вимагає присутності всього. required_array_keys як і раніше покриває другу половину.

Доступні два плейсхолдери для кастомних повідомлень: :values для прийнятих ключів та :unexpected для ключів, які фактично спричинили помилку (зазвичай це корисніше в API-відповідях):

$request->validate(
    ['options' => Rule::arrayKeys(['sort', 'direction'])],
    ['options.array_keys' => 'The :attribute field may not contain :unexpected.'],
);
// The options field may not contain colour.

Оскільки правило звітується як ArrayKeys у $validator->failed(), воно компонується з array, коли ви хочете, щоб обидві перевірки звітувалися незалежно. Rule::array() та його повідомлення залишаються без змін.

Виправлення уповільнення валідації з wildcards на великих масивах

Розгортання правил foo.*.bar було квадратичним відносно кількості розгорнутих атрибутів. ValidationRuleParser::explodeWildcardRules() накопичував результати, переприсвоюючи значення, що повертається з mergeRules(), який приймав накопичений набір за значенням, тому copy-on-write клонував весь набір правил один раз на кожен розгорнутий атрибут. Весь час витрачався в Validator::make(), ще до запуску будь-якого правила.

Числа з pull request при використанні 17 правил під одним wildcard:

  • 1,000 елементів: 0.98s → 0.11s
  • 4,000 елементів: 18.59s → 0.47s
  • 8,000 елементів: 85.13s → 0.98s

При 8,000 елементах payload становить лише близько 1.1 МБ, тому post_max_size та ліміти веб-сервера ніколи не спрацьовували. Правило max:500 на масиві теж не допомагало, оскільки розгортання відбувалося перед його виконанням.

Тіло злиття перенесено в приватний метод, який приймає акумулятор за посиланням. mergeRules() та mergeRulesForAttribute() зберігають свої сигнатури, але explodeWildcardRules() більше не маршрутизується через останній, тому override там більше не впливатиме на розгортання wildcards.

Виправлення Arr::forget(), що видаляв неправильний елемент

Arr::forget() скидав своє внутрішнє посилання назад до масиву верхнього рівня лише після обробки точного збігу ключа верхнього рівня. Після обробки ключа з крапкою посилання залишалося вказувати на вкладений масив, тому наступний ключ у списку розв'язувався відносно цього вкладеного масиву:

$array = ['users' => ['name' => 'Joe', 'id' => 1], 'id' => 99];
Arr::forget($array, ['users.name', 'id']);
// до: ['users' => [], 'id' => 99]
// після: ['users' => ['id' => 1]]

Видалявся неправильний елемент, а запитуваний зберігався, без жодної помилки. Переміщення скидання на початок циклу виправляє це для всього, що делегує до хелпера, включно з Arr::except(), Collection::except(), data_forget() та Uri::withoutQuery().

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

  • CompiledRouteCollection перебудовував кожен об'єкт Route при кожному виклику get(), getByAction() та getRoutesByMethod(), що робило 404 дорогими на закешованих маршрутах. Індекси пошуку з raw-атрибутів маршрутів прискорюють 404 проти 2,000 закешованих маршрутів з 71ms до 2.5ms
  • Аксесор для існуючого атрибута, який також був у $appends, отримував null замість збереженого значення, тому $model->price та $model->toArray()['price'] розходилися
  • Str::replace() та Str::remove() делегують до str_ireplace() для нечутливого до регістру пошуку, яка обробляє лише ASCII. Багатобайтові пошукові терміни тепер використовують патерн /iu; ASCII-терміни йдуть оригінальним шляхом
  • Резолв атрибута відношення всередині closure Relation::noConstraints() пропускав where-умову на первинному ключі. Новий Relation::withConstraints() обгортає резолв атрибутів
  • PostgresGrammar::wrapJsonPathAttributes() інтерполював JSON path атрибути в quoted SQL літерали без екранування одинарних лапок, на відміну від інших драйверів
  • Два псевдоніми, що вказують один на одного, змушували Container::getAlias() рекурсувати до вичерпання пам'яті; тепер кидається LogicException
  • NumberPrompt був єдиним типом промпту без fallback, тому number() кидав помилку на Windows, в неінтерактивних контекстах та в тестах замість деградації до Symfony question
  • ShouldBeUniqueUntilProcessing jobs тепер відстежують власника cache lock та звільняють через restoreLock(), тому retry не може звільнити lock, отриманий новішим dispatch
  • Резолв атрибута Guarded пропускався на Pivot, який перевизначає $guarded з [] і тому провалював перевірку дефолту ['*']
  • Затримки jobs поважаються при bulk push до QueueFake та FailoverQueue, а batch testing fakes використовують immutable timestamps
  • LengthAwarePaginator захищається від ділення на нуль, коли perPage дорівнює 0, а CursorPaginator переіндексує items консистентно в обох напрямках
  • Більшість Artisan-команд перейшли від стилю $name плюс getArguments()/getOptions() до одного рядка $signature
  • Логіка валідації URL була скоригована, і вирішено кілька PHP 8.5 deprecation попереджень щодо null array offset

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

Брейкінг-змін для типових застосунків не очікується. Дві зміни варто перевірити, якщо ви розширюєте framework internals: explodeWildcardRules() більше не викликає mergeRulesForAttribute(), тому override цього методу не вплине на розгортання wildcards, і Container::getAlias() тепер кидає LogicException на циклічних псевдонімах, які раніше вичерпували пам'ять. Підтримка HEIC залежить від вашої збірки Imagick з включеним HEIC-кодеком.

Два pull request, що злилися під час цього циклу, були відкочені перед релізом. Перегляньте changelog для деталей по кожному PR при оновленні.

0

Коментарі

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

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

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

Laravel Head
Новини 05 серпня 2026

Laravel Head: новий офіційний пакет для керування мета-тегами, Open Graph та JSON-LD

Laravel Head - свіжий офіційний пакет від команди Laravel, представлений на Laracon US 2026. Він надає зручний API для управління всіма елементами : заголовками, мета-описами, Open Graph, JSON-LD та ресурсними підказками у Blade, Livewire та Inertia додатках.

3
Laravel для Zed
Новини 05 серпня 2026

Офіційне розширення Laravel для Zed: LSP для PHP і Blade

Команда Laravel опублікувала офіційне розширення для редактора Zed, яке інтегрує Laravel LSP. Розширення надає автодоповнення, діагностику, підказки та інші можливості для роботи з PHP і Blade файлами, використовуючи знання про вашу Laravel-програму.

1

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

SushiBang
5 дн. тому

Middle Laravel / Filament Developer

Розробка та підтримка кастомної CRM-системи для доставки з використанням Laravel 12, Filament 5 та Livewire. Спеціаліст займатиметься проектуванням бази даних, розробкою модулів прийому/обробки замовлень, інтеграцією через REST API та оптимізацією. Вимагається глибоке розуміння Laravel, Filament та PostgreSQL, досвід з Livewire та SQL-оптимізацією. Важливі автономність і відповідальність.

Foxstone
14 дн. тому

Senior PHP Backend Developer (AI-First) - Laravel

Senior PHP Backend Developer з фокусом на AI-інструменти. Розробка масштабованих Laravel backend-додатків з TDD підходом (Pest/PHPUnit), розгортання на GCP (Cloud Run, Cloud SQL), оптимізація бази даних та написання високобезпечного коду. Вимагається 5+ років досвіду PHP/Laravel, hands-on GCP, практичний досвід AI-агентів (Gemini, Copilot, Cursor) для прискорення розробки.

Cargofy Inc.
17 дн. тому

Backend Engineer (PHP/Laravel)

Backend Engineer для AI-платформи логістики на PHP/Laravel. Розробка високонавантажених сервісів, API, event-driven пайплайнів для обробки сотень тисяч транзакцій щодня. Стек: PHP 8.x, Laravel, PostgreSQL, Redis, Horizon. Вимоги: 3+ років досвіду, глибоке розуміння Laravel, оптимізація високонавантажених систем, роботи з AI модулями. Самостійність і проактивність обов'язкові.

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

Image

intervention/image

Бібліотека для обробки зображень на PHP.

14,352 4.2.0 7

Laravel Medialibrary

spatie/laravel-medialibrary

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

6,155 11.23.3 13 6