🚀 Laravel Tips & Tricks

Коли я тільки почав працювати з Laravel, здавалося, що знаю все необхідне — моделі, контролери, маршрути. Але через рік практики зрозумів: фреймворк приховує десятки фішок (Laravel Tips), які роблять код чистішим, швидшим і приємнішим для підтримки. Сьогодні поділюся двадцятьма прийомами, які реально використовую в повсякденній розробці.

Зміст

Робота з Eloquent: коли ORM стає магією

Eloquent — це серце Laravel, але більшість розробників використовують лише 30% його можливостей. Давайте виправимо це.

1. Локальні скоупи для багаторазового використання

Замість дублювання запитів у різних місцях коду, створюйте методи-скоупи прямо в моделі. Це економить час і робить логіку зрозумілою.

// В моделі User
public function scopeActive($query)
{
    return $query->where('status', 'active');
}

public function scopeVerified($query)
{
    return $query->whereNotNull('email_verified_at');
}

// Використання
$users = User::active()->verified()->get();Code language: PHP (php)

Особисто мені це допомогло позбутися дублювання логіки у трьох різних контролерах одного проєкту для інтернет-магазину.

2. Eager Loading для оптимізації запитів

Проблема N+1 запитів — класична пастка. Якщо виводите список постів з авторами, без eager loading виконаєте сотні зайвих запитів до бази.

// Погано: N+1 запит
$posts = Post::all();
foreach($posts as $post) {
    echo $post->author->name; // окремий запит для кожного автора
}

// Добре: один запит з JOIN
$posts = Post::with('author')->get();Code language: PHP (php)

Плюси: швидкість зростає у 10-100 разів на великих вибірках. Мінуси: якщо жадібно завантажити зайві зв’язки, витрачається пам’ять даремно.

Laravel Eloquent Performance
Діаграма оптимізації Eloquent запитів з Eager Loading

3. Віртуальні атрибути (Accessors)

Іноді потрібно повернути дані в специфічному форматі, не змінюючи базу. Accessors дозволяють додати “віртуальні” поля до моделі.

// В моделі User
protected function fullName(): Attribute
{
    return Attribute::make(
        get: fn() => "{$this->first_name} {$this->last_name}"
    );
}

// Використання
echo $user->full_name; // "Іван Петренко"Code language: PHP (php)

4. Умовні запити з when()

Коли потрібно додати фільтр тільки за певної умови, метод when() робить код набагато чистішим за if-else конструкції.

$query = User::query();

$users = $query->when($request->role, function($q, $role) {
        return $q->where('role', $role);
    })
    ->when($request->verified, function($q) {
        return $q->whereNotNull('email_verified_at');
    })
    ->get();Code language: PHP (php)

Цей підхід особливо зручний для фільтрації даних на основі GET-параметрів.

Маршрутизація і контролери: чистота і швидкість

5. Route Model Binding

Забудьте про ручний пошук моделі за ID. Laravel автоматично підставить потрібну модель у параметр методу.

// routes/web.php
Route::get('/posts/{post}', [PostController::class, 'show']);

// В контролері
public function show(Post $post)
{
    return view('posts.show', compact('post'));
    // Laravel сам знайде Post::findOrFail($id)
}Code language: PHP (php)

Плюси: менше коду, автоматична обробка 404. Мінуси: якщо потрібна специфічна логіка пошуку (наприклад, з додатковими умовами), доведеться перевизначати метод в моделі.

6. Групування маршрутів з префіксом

Для адмін-панелі чи API зручно об’єднати маршрути в групи з спільним префіксом і middleware.

Route::prefix('admin')->middleware('auth:admin')->group(function() {
    Route::get('/dashboard', [AdminController::class, 'dashboard']);
    Route::get('/users', [AdminController::class, 'users']);
    Route::get('/settings', [AdminController::class, 'settings']);
});Code language: PHP (php)

7. Fallback маршрут для 404

Стандартна сторінка помилки виглядає нудно. Створіть власний fallback для невідомих URL.

Route::fallback(function() {
    return view('errors.custom-404');
});Code language: PHP (php)

Валідація і форми: захист і зручність

8. Form Request класи для складної валідації

Не вантажте контролери валідацією. Винесіть логіку у окремий клас.

php artisan make:request StorePostRequest

// В StorePostRequest
public function rules()
{
    return [
        'title' => 'required|max:255',
        'content' => 'required|min:100',
        'category_id' => 'exists:categories,id'
    ];
}

// В контролері
public function store(StorePostRequest $request)
{
    // Дані вже провалідовані
    Post::create($request->validated());
}Code language: PHP (php)

9. Власні правила валідації

Іноді потрібна унікальна логіка перевірки. Створіть власне правило через artisan.

php artisan make:rule Uppercase

// В класі Uppercase
public function passes($attribute, $value)
{
    return strtoupper($value) === $value;
}

// Використання
'name' => ['required', new Uppercase]Code language: PHP (php)

Робота з даними: колекції і кеш

10. Методи колекцій замість циклів

Laravel Collections — це обгортка над масивами з десятками корисних методів. Забудьте про foreach де це можливо.

$users = User::all();

// Замість циклу
$activeUsers = $users->filter(fn($u) => $u->is_active)
                     ->map(fn($u) => $u->name)
                     ->unique()
                     ->values();Code language: PHP (php)

Це читабельніше і працює швидше за рахунок внутрішньої оптимізації.

11. Кешування запитів з remember()

Якщо запит до бази виконується часто, а дані рідко змінюються — кешуйте результат.

$categories = Cache::remember('categories', 3600, function() {
    return Category::with('posts')->get();
});Code language: PHP (php)

Плюси: навантаження на базу падає в рази. Мінуси: треба не забувати скидати кеш при зміні даних.

Laravel Cache Strategy
Схема стратегії кешування в Laravel додатках

12. Ліниве завантаження з lazy()

Коли потрібно обробити тисячі записів, метод lazy() завантажує дані порціями, не з’їдаючи всю пам’ять.

User::lazy()->each(function($user) {
    // обробка кожного користувача
    // без завантаження всіх у пам'ять одночасно
});Code language: PHP (php)

Blade шаблони: швидкість і гнучкість

13. Компоненти класів для складних блоків

Blade-компоненти дозволяють винести логіку з шаблонів у PHP-класи.

php artisan make:component Alert

// В Alert.php
public function __construct(public string $type = 'info') {}

// В шаблоні
<x-alert type="success">
    Дані збережено!
</x-alert>Code language: PHP (php)

14. @once директива для скриптів

Якщо компонент використовується кілька разів на сторінці, а скрипт потрібен один — оберніть його в @once.

@once
    <script src="/js/chart.js"></script>
@endonceCode language: HTML, XML (xml)

15. @production і @env директиви

Показуйте різний код залежно від середовища — зручно для аналітики або дебаг-панелей.

@production
    <!-- Google Analytics -->
@endproduction

@env('local')
    <div class="debug-bar">Debug mode</div>
@endenvCode language: HTML, XML (xml)

Тестування і дебаг: впевненість у коді

16. Feature тести для критичних сценаріїв

Тестуйте реальні користувацькі сценарії — реєстрацію, оплату, вихід з системи. Більше інформації про тестування можна знайти в гайді по PHPUnit.

public function test_user_can_create_post()
{
    $user = User::factory()->create();
    
    $response = $this->actingAs($user)
                     ->post('/posts', [
                         'title' => 'Test',
                         'content' => 'Content'
                     ]);
    
    $response->assertStatus(201);
    $this->assertDatabaseHas('posts', ['title' => 'Test']);
}Code language: PHP (php)

17. Ray для дебагу без dd()

Інструмент Ray від Spatie дозволяє дебажити додаток без зупинки виконання. Альтернатива Telescope для швидкого перегляду змінних.

ray($user)->blue();
ray()->table($posts);
ray()->pause(); // зупинить виконання до клікуCode language: PHP (php)

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

Продуктивність і безпека

18. Queue для важких завдань

Відправка листів, генерація PDF, обробка зображень — все це не має блокувати HTTP-відповідь. Використовуйте черги.

// Створення Job
php artisan make:job SendWelcomeEmail

// Відправка в чергу
SendWelcomeEmail::dispatch($user);Code language: PHP (php)

Детальніше про організацію черг читайте у статті про RabbitMQ для PHP.

19. Rate Limiting для API

Захистіть API від перевантаження за допомогою вбудованого throttle middleware.

Route::middleware('throttle:60,1')->group(function() {
    Route::get('/api/posts', [ApiController::class, 'posts']);
    // максимум 60 запитів на хвилину
});Code language: PHP (php)

20. Horizon для моніторингу черг

Якщо використовуєте Redis для черг, встановіть Laravel Horizon. Це дасть зручний веб-інтерфейс для моніторингу завдань.

composer require laravel/horizon
php artisan horizon:install
php artisan horizonCode language: JavaScript (javascript)
Laravel Horizon Dashboard - AI generated
Інтерфейс Laravel Horizon для моніторингу черг

Висновок: практика робить майстра (Laravel Tips)

Ці двадцять прийомів — не просто теорія з документації. Кожен з них перевірений на реальних проєктах і економить години розробки щомісяця. Почніть впроваджувати їх поступово: сьогодні додайте скоупи в моделі, завтра винесіть валідацію у Form Request, післязавтра налаштуйте кешування. За місяць ваш код стане набагато чистішим і швидшим.

Laravel — це не просто фреймворк, це екосистема інструментів. Продовжуйте досліджувати офіційну документацію, дивіться код на GitHub, експериментуйте. Кожна нова фіча, яку ви освоїте, зробить вас кращим розробником.

Рекомендуємо прочитати

Залишити відповідь

Ваша e-mail адреса не оприлюднюватиметься. Обов’язкові поля позначені *