Вбудована обробка зображень у Laravel 13.20

Перекладено ШІ 0 Laravel News 16 липня, 2026

Laravel 13.20.0 отримав нативну підтримку обробки зображень та новий атрибут #[WithoutMiddleware] для зручного керування контролерами. Оновлення також приносить корисні покращення для Eloquent та Redis, що робить щоденну розробку ще ефективнішою.

У Laravel 13.20.0 з’явилася нативна підтримка обробки зображень — вбудований API на основі драйверів для роботи з файлами із завантажень, сховища, URL або сирих байтів. Також реліз містить атрибут контролера WithoutMiddleware, окремий префікс сесій для Redis та низку покращень для Eloquent і черг.

  • Вбудована обробка зображень через новий Facade Image
  • Новий атрибут контролера #[WithoutMiddleware]
  • Окремий префікс Redis для сесій
  • «Тихе» (без виклику подій) інкрементування та декрементування в моделях Eloquent
  • Підтримка Enums як ключів для WithoutOverlapping у чергах
  • Та багато іншого

# Що нового

# Нативна обробка зображень

Laravel 13.20 представляє компонент Illuminate\Image, який дозволяє змінювати розмір, обрізати, конвертувати формати та зберігати зображення без використання сторонніх обгорток.

Зображення є незмінними (immutable): кожна трансформація повертає новий екземпляр, а всі заплановані зміни застосовуються лише у момент запиту результату.

Найпопулярніший сценарій — робота із завантаженим файлом. Метод Request::image() повертає екземпляр Image для заданого ключа або null, якщо файл відсутній:

$request->image('avatar')
    ->cover(200, 200)
    ->toWebp()
    ->store('avatars');

Також можна створити об'єкт зображення зі шляху, URL, сирих байтів, base64 або безпосередньо зі сховища:

Image::fromPath('/path/to/photo.jpg');
Image::fromUrl('https://example.com/photo.jpg');
Image::fromBytes($bytes);
Image::fromStorage('photos/avatar.jpg', 's3');
 
Storage::disk('s3')->image('photos/avatar.jpg');

Для роботи з екземпляром доступні методи трансформації, налаштування виводу та інспектування:

// Трансформації...
$image->cover(200, 200);
$image->contain(800, 600);
$image->crop(200, 200);
$image->resize(1024, 768);
$image->scale(1200, 800);
$image->rotate(90);
$image->blur(10);
$image->sharpen(10);
$image->grayscale();
$image->flip();
$image->flop();
$image->orient(); // Застосовує поворот на основі EXIF...
 
// Формат виводу та якість...
$image->toWebp();
$image->toJpg()->quality(80);
$image->optimize(); // WebP з якістю 70...
$image->optimize('jpg', 85);
 
// Читання та аналіз...
$image->toBytes();
$image->toBase64();
$image->toDataUri();
$image->width();
$image->height();
$image->dimensions();
$image->mimeType();
$image->extension();

Завдяки незмінності об'єктів, ви можете створювати кілька варіацій на основі одного джерела:

$image = $request->image('photo');
 
$image->cover(200, 200)->toWebp()->store('thumbnails');
$image->grayscale()->toWebp()->store('grayscale');

Компонент постачається з двома драйверами на базі Intervention Image v4: GD та Imagick. Ви можете обрати драйвер для конкретного зображення, а Facade Image дозволяє перевизначити логіку трансформацій:

use Illuminate\Image\Transformations\Sharpen;
 
// Вибір драйвера для зображення...
$image->using('imagick');
$image->usingGd();
$image->usingImagick();
 
// Перевизначення обробки трансформації для драйвера...
Image::transformUsing('gd', Sharpen::class, function ($image, Sharpen $sharpen) {
    // Кастомна логіка sharpen для драйвера GD...
 
    return $image;
});

Intervention Image є рекомендованою залежністю, тому її потрібно встановити вручну:

composer require intervention/image

Детальніше у #59276.

# Атрибут контролера #[WithoutMiddleware]

До атрибутів маршрутизації додали аналог #[Middleware]. Якщо останній призначає Middleware для класу чи методу, то #[WithoutMiddleware] дозволяє їх виключати на рівні атрибутів:

use App\Http\Middleware\EnsureTokenIsValid;
use Illuminate\Routing\Controllers\Attributes\Middleware;
use Illuminate\Routing\Controllers\Attributes\WithoutMiddleware;
 
#[Middleware(EnsureTokenIsValid::class)]
class UserController
{
    public function index()
    {
        // Middleware діє тут...
    }
 
    #[WithoutMiddleware(EnsureTokenIsValid::class)]
    public function profile()
    {
        // ...але не тут.
    }
}

Перевірка відповідності використовує ReflectionAttribute::IS_INSTANCEOF, тому підкласи Middleware також будуть виключені. Дивіться #60709.

# Префікс для сесій у Redis

Раніше, якщо SESSION_DRIVER та CACHE_STORE одночасно вказували на Redis, сесії успадковували префікс кешу. Це ускладнювало ідентифікацію ключів сесій під час очищення або налагодження. Нова опція prefix у config/session.php дозволяє задати окремий префікс:

'prefix' => env('SESSION_PREFIX', Str::slug((string) env('APP_NAME', 'laravel')).'-session-'),

Сховище кешу клонується перед застосуванням префікса сесії, тому це не впливає на ключі кешу. Опція є опціональною. Дивіться #60700.

# Тихе масове оновлення в Eloquent

В Eloquent вже існували методи incrementQuietly() та decrementQuietly() для окремих колонок. Тепер додано методи incrementEachQuietly() та decrementEachQuietly(), які дозволяють оновлювати кілька колонок одночасно без виклику подій моделі:

$user->incrementEachQuietly(['posts_count' => 1, 'points' => 10]);
 
$user->decrementEachQuietly(['credits' => 3, 'tokens' => 2]);

Дивіться #60720 та виправлення для динамічних викликів у #60737.

# Enums як ключі для запобігання накладанню завдань

Middleware WithoutOverlapping тепер приймає PHP Enums як ключ. Це позбавляє необхідності вручну конвертувати перерахування у рядок:

class UpdateCategory implements ShouldQueue
{
    use Queueable;
 
    public function __construct(protected Category $category) {}
 
    public function middleware(): array
    {
        return [new WithoutOverlapping($this->category)];
    }
}

Зміна повністю сумісна з існуючими рядковими ключами. Дивіться #60722.

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

  • Колбеки beforePushing() та afterPushing() у QueueFake (#60689), а метод MailFake::assertQueuedTimes() став публічним (#60710)
  • У Facade Storage додано assertEmpty() (#60658), а в подію WorkerStopping — звіт про використання пам'яті (#60613)
  • make:migration тепер генерує префікси таймстемпів без колізій (#60771)
  • Атрибут #[SensitiveParameter] додано до параметрів із секретними даними, щоб вони не потрапляли у stack traces (#60753)
  • Параметр capitalize для методу Stringable::initials() (#60741)
  • Str::containsAll() більше не повертає true для порожнього масиву (#60746), а Number::forHumans() та abbreviate() не повертають -0 для мізерних від'ємних значень (#60736, #60768)
  • Виправлено BelongsToMany::touch() для випадків, коли ключ не є id (#60708), роботу TrustProxies з at:* та покращено providesTemporaryUploadUrls() для S3 (#60755)

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

Для стандартних застосунків критичних змін не очікується. Драйвери компонента зображень потребують intervention/image (^4.0). Встановіть цей пакет перед використанням Facade Image.

Посилання

Популярні

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

12 Оновлено 26 червня, 2026

Генерація документації в Laravel за допомогою штучного інтелекту

Docudoodle — це потужний пакет для генерації документації в Laravel, який допомагає легко аналізувати вашу кодову базу та створювати документацію за допомогою обраного вами AI. Чи готові ви дізнатися, як цей інструмент може спростити вашу роботу з документуванням коду? Читайте далі!

50 Оновлено 26 червня, 2026

Nuxt 3 + Laravel Sanctum: Просте та надійне рішення для автентифікації вашого SPA та API

У сучасній веб-розробці аутентифікація є ключовою для захисту додатків і даних користувачів. Дізнайтеся, як модуль nuxt-sanctum-authentication спростить інтеграцію між Nuxt 3 та Laravel Sanctum, забезпечуючи надійний і зручний спосіб реалізації аутентифікації для вашого проєкту

Використання повнотекстового пошуку в Laravel
178 Оновлено 26 червня, 2026

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

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