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

Олексій Бабінцев

@alexbabintsev

Lead / Architect Laravel Developer
Київ, Україна
На сайті з 14 червня 2026

Навички

PHP Laravel PostgreSQL

Ачивки

Перший крок
Laracon US 2026: відео першого дня вже доступне Рекомендовано
Новини 29 липня 2026

Laracon US 2026: відео першого дня вже доступне

У Бостоні стартував Laracon US 2026, і запис першого дня вже доступний. Головне з кейноуту: офіційний Laravel LSP для редакторів, Laravel Cloud деплоїть Hono, Flask, Go та Rails, Pest 5 із Tia Engine. Аарон Френсіс приєднався до команди Laravel.

Pest 5: Tia Engine, плагін для AI-агентів і evals для LLM
Новини 29 липня 2026

Pest 5: Tia Engine, плагін для AI-агентів і evals для LLM

На першому дні Laracon US 2026 Нуно Мадуро представив Pest 5. Головне - Tia Engine, що переганяє лише зачеплені змінами тести й скорочує десятихвилинний прогін до кількох секунд, плюс плагіни для AI-агентів, evals, PHPStan і Rector.

Прихований N+1 у Livewire: реєстри на час запиту Рекомендовано
Посібники 28 липня 2026
Як будувався laravelukraine.com

Прихований N+1 у Livewire: реєстри на час запиту

Найпідступніше джерело зайвих запитів - список із однаковою кнопкою на кожній картці, де кожна тихо робить свій SELECT. Розбираємо, як per-request реєстр збирає сотні однакових перевірок в один запит, чому саме scoped(), і той самий патерн поза базою.

Tips 27 липня 2026

touch() - автооновлення timestamps у батьків

Додали коментар до поста, а updated_at у поста не змінився. Кеш не оновився.

touch() дозволяє автоматично оновлювати час оновлення батьківської моделі.

Як працює:

У дочірній моделі вказуємо $touches. Коли вона зберігається - оновлюється updated_at у батьків.

Де корисно:

  • Інвалідація кешу за timestamp
  • "Остання активність"
  • Відстеження змін контенту

Працює з будь-якими зв'язками.

class Comment extends Model
{
  // Авто-touch для поста
  protected $touches = ['post'];

  public function post()
  {
    return $this->belongsTo(Post::class);
  }
}

// Тепер при створенні/оновленні коментаря
$comment = new Comment(['body' => 'Great post!']);
$comment->post()->associate($post);
$comment->save();
// updated_at у Post буде оновлено

// Ручне оновлення timestamps
$post->touch();

// Touch кількох зв'язків
class Comment extends Model
{
  protected $touches = ['post', 'author'];
}
SimpleStats
Новини 21 липня 2026

Об'єднана аналітична система для Laravel: трафік, дохід та атрибуція в одному місці

Більшість Laravel SaaS використовують три окремі інструменти для аналітики: трафік, доходи та атрибуцію реклами. SimpleStats пропонує об'єднати їх у єдину серверну систему, яка відстежує весь шлях клієнта від першого візиту до оплати в одному місці.

Найдешевший запит - той, якого немає: eager loading і лічильники Рекомендовано
Посібники 20 липня 2026
Як будувався laravelukraine.com

Найдешевший запит - той, якого немає: eager loading і лічильники

Найдешевший запит - той, якого немає. З цього починаємо серію про продуктивність laravelukraine.com. Eager loading проти N+1 у зв'язках - зокрема підступний випадок аватарів через Spatie MediaLibrary, де забутий author.media повертає прихований запит на кожен рядок. Плюс withCount/loadCount замість ручних COUNT і чому іноді найправильніше рішення - взагалі не кешувати.

Tips 17 липня 2026

Soft Deletes - ніколи не втрачайте дані

Користувач випадково видалив свій акаунт. Відновити не можна. Негатив забезпечено.

Soft Deletes позначають запис як видалений, але фактично не прибирають його з бази.

Як працює:

Додаємо поле deleted_at, а Laravel автоматично приховує такі записи.

Корисні методи:

  • forceDelete() - повне видалення
  • withTrashed() - включити видалені
  • onlyTrashed() - лише видалені
  • restore() - відновити

Порада: Сумісно з GDPR: можна відновити за 30 днів, а потім зробити force delete.

// Міграція
Schema::table('users', function (Blueprint $table) {
  $table->softDeletes();
});

// Модель
use Illuminate\Database\Eloquent\SoftDeletes;

class User extends Model
{
  use SoftDeletes;
}

// Використання
$user->delete(); // Soft delete
$user->forceDelete(); // Повне видалення

// Запити
User::all(); // Тільки активні
User::withTrashed()->get(); // Включно з видаленими
User::onlyTrashed()->get(); // Лише видалені

// Відновлення
$user = User::withTrashed()->find(1);
$user->restore();

// Перевірка
if ($user->trashed()) {
  // Користувач видалений
}
Laravel Cooldown
Новини 17 липня 2026

Laravel Cooldown: пакет для контролю часових інтервалів між діями

Laravel Cooldown - новий пакет від Mahedi Zaman Zaber, який дозволяє встановлювати часові блокування на конкретні дії: обмеження повторної відправки OTP, інтервали між запитами на скидання пароля, затримки перед повторними спробами платежів та інші сценарії з очікуванням.

Legacy Bridge
Новини 16 липня 2026

Laravel Legacy Bridge: перенесення автентифікованих сесій зі застарілих додатків у Laravel

Пакет Laravel Legacy Bridge від Кріса Келлера дозволяє поступово мігрувати застарілі PHP-додатки на Laravel, зберігаючи автентифіковані сесії користувачів. Middleware автоматично зчитує legacy-сесії, декодує payload і автентифікує користувачів без повторного входу.

Патерн Interpreter
Посібники 14 липня 2026
Патерни проєктування

Interpreter - обробка власних правил

Описує правила у вигляді невеликої власної мови (DSL) і обчислює їх. Як комбінувати прості вирази в дерево умов і коли краще взяти готовий парсер.

Патерн Chain of Responsibility
Посібники 08 липня 2026
Патерни проєктування

Chain of Responsibility - ланцюжок обробників

Передає запит ланцюжком обробників, кожен з яких обробляє його або передає далі. Як це лягає на послідовні валідатори та Pipeline у Laravel.

EnvKit
Новини 07 липня 2026

EnvKit: локальний стек для розробки Laravel на Windows і macOS

EnvKit - безкоштовний десктопний додаток для Windows і macOS, який об'єднує веб-сервер, PHP, бази даних і допоміжні сервіси в єдиній панелі керування. Альтернатива Laragon, XAMPP і Laravel Herd з підтримкою MySQL, PostgreSQL, MongoDB, Redis та вбудованою AI-інтеграцією.

DDLess
Новини 07 липня 2026

Чого бракує вашому PHP-середовищу розробки

DDLess - нова альтернатива традиційному дебагінгу у Laravel. ПокроковийDebugGer без налаштувань, інтерактивний Playground всередині точок зупинки та Task Runner з повним доступом до додатка. Працює локально безкоштовно.

Tips 02 липня 2026

Уникати select(*) в продакшені

Завантаження всіх колонок? Витрачається пам'ять та пропускну здатність.

Обирай тільки колонки які реально використовуєш. Менший об'єм даних. Швидші запити. Менше пам'яті.

Прихована ціна:

Текстові колонки можуть бути величезними. JSON колонки ще більші. Timestamps які можливо не потрібні.

Перевага індексу:

Запити з меншою кількістю колонок можуть використовувати covering індекси.

Порада: Профілюй з EXPLAIN щоб побачити чи запит використовує index-only scan.

// ПОГАНО: Завантажує все включаючи великі текстові поля
$posts = Post::where('published', true)->get();

// ДОБРЕ: Тільки потрібні колонки
$posts = Post::select('id', 'title', 'slug', 'published_at')
    ->where('published', true)
    ->get();

// Приклад API відповіді
public function index()
{
    return Post::select([
            'id',
            'title',
            'slug',
            'excerpt',
            'published_at',
        ])
        ->with('author:id,name,avatar')
        ->where('published', true)
        ->paginate(20);
}

// Dropdown/автозаповнення
$users = User::select('id', 'name')
    ->where('active', true)
    ->get();

// Зі зв'язками - вказуй колонки для обох
$posts = Post::select('id', 'title', 'author_id')
    ->with('author:id,name')
    ->get();
Laravel 13.18
Новини 02 липня 2026

Метрики воркерів у події WorkerStopping у Laravel 13.18

Laravel 13.18.0 додає метрики воркерів до події WorkerStopping, коректне опрацювання сигналів завершення для schedule:work, пріоритетну реєстрацію команд artisan dev та низку виправлень у Number-хелперах, кеші та планувальнику.

Tips 01 липня 2026

selectRaw() для обчислюваних колонок

Потрібні обчислені колонки без завантаження повних моделей?

selectRaw() робить обчислення на рівні SQL. База даних обробляє. Повертає тільки результати.

Поширене використання:

  • Ціна з податком
  • Вік з дати народження
  • Обчислення відстані
  • Об'єднані рядки

Виграш продуктивності:

База даних робить математику. Не PHP. Повертає тільки те що потрібно.

Порада: Завжди використовувати parameter binding щоб запобігти SQL ін'єкції.

// Обчислення на стороні бази даних
$products = Product::selectRaw('
    id,
    name,
    price,
    price * 1.2 as price_with_tax,
    price * quantity as total
')->get();

// Обчислення віку
$users = User::selectRaw('
    id,
    name,
    YEAR(CURDATE()) - YEAR(birthdate) as age
')->get();

// Конкатенація
$users = User::selectRaw("
    CONCAT(first_name, ' ', last_name) as full_name,
    email
")->get();

// Безпечний parameter binding
$taxRate = 1.15;
$products = Product::selectRaw(
    'price * ? as price_with_tax',
    [$taxRate]
)->get();
// Обчислення відстані
$lat = 40.7128;
$lng = -74.0060;

$stores = Store::selectRaw("
    *,
    (6371 * acos(cos(radians(?))
    * cos(radians(lat))
    * cos(radians(lng) - radians(?))
    + sin(radians(?))
    * sin(radians(lat)))) AS distance
", [$lat, $lng, $lat])
    ->having('distance', '<', 10)
    ->orderBy('distance')
    ->get();

// Складні обчислення з декількома параметрами
$discount = 0.1;
$minPrice = 100;

$items = Product::selectRaw('
    id,
    name,
    price,
    price * (1 - ?) as discounted_price,
    CASE WHEN price > ? THEN "premium" ELSE "standard" END as tier
', [$discount, $minPrice])->get();
Testing AI без API
Новини 01 липня 2026

Тестування AI-систем у Laravel без жодного виклику API

У десятому епізоді серії Ship AI with Laravel показано, як тестувати повноцінну AI-платформу за допомогою Pest без витрат на API-виклики. Використовуючи систему фейків SDK, можна перевіряти агентів, інструменти, векторні бази знань та чат-потоки з детермінованими результатами.

Tips 29 червня 2026

toBase() - скидання накладних витрат Eloquent

Потрібна сира продуктивність? Eloquent моделі додають накладні витрати.

toBase() конвертує запит в базовий query builder. Без гідратації моделі.

Повертає stdClass замість моделей. Швидше. Менше пам'яті.

Коли використовувати:

  • Великі експорти де не потрібні методи моделі
  • Запити агрегації
  • Трансформація даних перед відправкою в API
  • Фонова обробка

Компроміс:

Немає accessors, mutators або зв'язків. Тільки сирі дані.

Порада: Використовувати для операцій тільки читання на великих наборах даних.

// ПОГАНО: Створює 10,000 Eloquent моделей
$users = User::where('active', true)->get();

// ДОБРЕ: Повертає stdClass об'єкти
$users = User::where('active', true)
    ->toBase()
    ->get();

// Приклад: Експорт в CSV
$users = User::select('name', 'email')
    ->toBase()
    ->get();

foreach ($users as $user) {
    // $user це stdClass, не User модель
    fputcsv($file, [$user->name, $user->email]);
}

// Працює з chunk теж
User::where('active', true)
    ->toBase()
    ->chunk(1000, function($users) {
        // Обробка без накладних витрат моделі
    });
Tips 27 червня 2026

DB::raw() - коли Eloquent недостатньо

Потрібен складний SQL? Функції дат? Математичні операції?

Eloquent має межі. DB::raw() дозволяє писати сирий SQL всередині запитів.

Поширені випадки використання:

  • Функції дати/часу
  • Математичні операції
  • Специфічні для бази даних функції
  • Складна агрегація

Попередження безпеки:

Ніколи не передавай вхідні дані користувача безпосередньо в raw(). Використовувати біндінги.

Порада: Розглянь власні query scopes щоб повторно використовувати складні raw вирази.

// Функції дат
$users = User::where('created_at', '>=',
    DB::raw('DATE_SUB(NOW(), INTERVAL 30 DAY)')
)->get();

// Математичні операції
$products = Product::select('*',
    DB::raw('price * quantity as total')
)->get();

// CASE вирази
$posts = Post::select('*',
    DB::raw('CASE WHEN views > 1000 THEN "popular"
             ELSE "regular" END as status')
)->get();

// Агрегація з групуванням
$stats = Order::select(
    DB::raw('DATE(created_at) as date'),
    DB::raw('SUM(total) as revenue'),
    DB::raw('COUNT(*) as orders')
)
->groupBy('date')
->get();

// БЕЗПЕЧНО: Використання біндінгів
$status = 'published';
Post::whereRaw('LOWER(status) = ?', [strtolower($status)])->get();
Filament Optimization
Новини 27 червня 2026

Допоможіть зробити Filament швидшим!

Команда Filament запускає бета-версії v4.12 та v5.7 з масштабними оптимізаціями продуктивності. Розробники можуть вже сьогодні протестувати нову версію у своїх додатках та поділитися результатами з командою.

Signal
Новини 27 червня 2026

Signal - бібліотека для генерації документації з PHP-атрибутів

Signal від Стіва Макдугала перетворює PHP-атрибути на класах і методах у повноцінну документацію. Бібліотека зчитує анотації безпосередньо з коду та генерує Markdown для розробників і JSON для інструментів, тримаючи документацію актуальною поруч із кодом.

Tips 26 червня 2026

remember() - кешування результатів запитів

Той самий запит виконується 100 разів за секунду. База даних потіє.

Закешування результатів. Звернись до бази один раз, обслуговуй з кешу.

Спосіб Laravel:

Використовувати remember() на запитах. Автоматично кешує результати з тегами.

Коли кешувати:

  • Дані змінюються рідко (категорії, налаштування)
  • Дорогі запити (join'и, агрегація)
  • Сторінки з високим трафіком

Інвалідація кешу:

Очищати кеш коли дані змінюються використовуючи події моделі.

Порада: Використовувати короткий час кешування (5-15 хвилин) для даних що змінюються іноді.

// ПОГАНО: Звертається до бази кожен раз
$categories = Category::all();

// ДОБРЕ: Кеш на 1 годину
$categories = Cache::remember('categories', 3600, fn() =>
    Category::all()
);

// Використання query builder
$activeUsers = User::where('active', true)->remember(600)->get(); // 10 хвилин

// Кеш з тегами
$posts = Cache::tags(['posts', 'homepage'])
    ->remember('posts.featured', 3600, function () {
        return Post::where('featured', true)->get();
    });

// Інвалідація при події моделі
class Post extends Model
{
    protected static function boot()
    {
        parent::boot();
        static::saved(function () {
            Cache::tags('posts')->flush();
        });
    }
}
// Вічний кеш (ручна інвалідація)
$settings = Cache::rememberForever('settings', fn() =>
    Setting::pluck('value', 'key')
);

// Ключ кешу з параметрами
$userId = 5;
$posts = Cache::remember("user_{$userId}_posts", 3600,
    fn() => Post::where('user_id', $userId)->get()
);

// Умовне кешування
if (config('cache.enabled')) {
    $data = Cache::remember('key', 3600, fn() => expensiveQuery());
} else {
    $data = expensiveQuery();
}

// Очистити конкретний кеш
Cache::forget('categories');

// Очистити тегований кеш
Cache::tags(['posts'])->flush();

// Перевірити чи закешовано
if (Cache::has('categories')) {
    $categories = Cache::get('categories');
}
Патерн Composite
Посібники 23 червня 2026
Патерни проєктування

Composite - дерево об'єктів

Патерн Composite дозволяє працювати з деревом об'єктів так само, як з одним об'єктом. І окремий «лист», і «гілка» (група) реалізують той самий інтерфейс, тож клієнт викликає в них однакові методи.

Патерн Bridge
Посібники 20 червня 2026
Патерни проєктування

Bridge - відокремлення абстракції

Патерн Bridge розділяє абстракцію та її реалізацію на дві окремі ієрархії, щоб змінювати їх незалежно. Це рятує, коли є кілька незалежних вимірів варіативності і за наївного підходу класи множаться комбінаторно.

Vigilance
Новини 20 червня 2026

Vigilance - комплексний інструмент моніторингу черг, команд та планувальника Laravel

Vigilance - це панель моніторингу для Laravel, яка відстежує черги, artisan-команди та заплановані завдання незалежно від драйвера (Redis, SQS, database). Записує кожен запуск з параметрами, кодами завершення та трасами винятків.

Що нового в PostgreSQL 19: графові запити, GROUP BY ALL і крок до "універсальної" бази даних.
Новини 19 червня 2026

Що нового в PostgreSQL 19: графові запити, GROUP BY ALL і крок до "універсальної" бази даних.

PostgreSQL 19 продовжує важливу тенденцію останніх років: класична реляційна база даних поступово перетворюється на універсальну платформу для роботи з різними типами даних - від JSON до графів і аналітики

Історія PHP
Новини 19 червня 2026

Вийшов тизер документального фільму «Історія PHP»

CultRepo представила тизер документального фільму про PHP - мову програмування, на якій побудовано Laravel та величезну частину інтернету. Фільм за підтримки JetBrains розповість історію від спагетті-коду до сучасних фреймворків, а в ньому візьмуть участь творці Laravel, Composer та Symfony.

Команда artisan dev у Laravel 13.16.0
Новини 18 червня 2026

Команда artisan dev у Laravel 13.16.0

Laravel 13.16.0 додає команду php artisan dev для одночасного запуску сервера, черг, логів та Vite, метод whenFilledEnum() для типізованої роботи з enum, можливість додавати кілька cookies до будь-якої відповіді та драйвер array для режиму обслуговування при паралельному тестуванні.

Filament Storage Monitor
Новини 17 червня 2026

Filament Storage Monitor: відстежуйте використання дискового простору у Filament-панелі

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

Laradocs
Новини 14 червня 2026

Laradocs: пакет для створення версійованої документації в Laravel-додатках

Laradocs - Laravel-пакет для розгортання документаційного сайту з Markdown-файлів усередині вашого коду. Пишіть документацію поруч із кодом, комітьте разом, а Laradocs рендерить її за адресою /docs з навігацією, SEO-метаданими та адаптивним інтерфейсом.

Відкрито опитування State of PHP 2026
Новини 14 червня 2026

Відкрито опитування State of PHP 2026

JetBrains та The PHP Foundation запустили перше спільне опитування State of PHP 2026, щоб отримати детальну картину сучасного використання PHP. Опитування охоплює досвід розробників, їхні інструменти, ставлення до AI та виклики у роботі.

Laracon US 2026 оголосив повний список доповідачів
Новини 14 червня 2026

Laracon US 2026 оголосив повний список доповідачів

Laracon US представив повний склад спікерів для конференції 2026 року, яка відбудеться в Бостоні 28-29 липня. Список включає команду Laravel Core, відомих представників спільноти та спікерів поза межами фреймворку.

Патерн Singleton
Посібники 13 червня 2026
Патерни проєктування

Singleton - один екземпляр

Патерн Singleton гарантує один екземпляр класу на весь застосунок. У Laravel замість класичного Singleton зі static-властивістю та приватним конструктором використовують контейнерний singleton: app()->singleton(...). Контейнер створює об'єкт один раз і повертає той самий екземпляр на всі залежно

Патерн Factory Method
Посібники 07 червня 2026
Патерни проєктування

Factory Method - вибір створення

Factory Method переносить рішення про створення конкретного об'єкта у підкласи. Базовий клас задає загальний алгоритм, а який саме об'єкт створити - вирішує нащадок. Це допомагає розширювати логіку без змін у базовому класі (принцип відкритості/закритості).

Tips 10 квітня 2026

sole() - суворе отримання одного результату

Запит має повернути рівно один запис. Повертає нуль або декілька? Це баг.

first() мовчки повертає null. sole() кидає виняток якщо не рівно один.

Коли використовувати:

  • Отримання за унікальним ідентифікатором
  • Коли декілька результатів вказують на пошкодження даних
  • Критична бізнес-логіка

Винятки що кидаються:

  • RecordsNotFoundException - нуль результатів
  • MultipleRecordsFoundException - більше одного

Порада: Використовувати у фінансових операціях де очікується рівно один запис.

// ПОГАНО: Мовчки повертає null або перший з багатьох
$user = User::where('email', $email)->first();
// Що якщо є дублікати? Мовчазний баг.

// ДОБРЕ: Гарантує рівно один результат
try {
    $user = User::where('email', $email)->sole();
    // Гарантовано єдиний користувач що підходить
} catch (RecordsNotFoundException $e) {
    // Користувач не знайдений
} catch (MultipleRecordsFoundException $e) {
    // Пошкодження даних - існують дублікати
}

// В обробці рахунків
$invoice = Invoice::where('invoice_number', $number)->sole();
// Дублікати були б серйозним багом

// firstOr vs soleOr
$user = User::where('email', $email)->soleOr(function () {
    throw new UserNotFoundException();
});

// Зі зв'язками
$user = User::with('profile')->where('id', $id)->sole();
Tips 27 березня 2026

whereIn() з великими масивами - пастка пам'яті

Передавання 10,000 ID в whereIn()? Рядок запиту стає величезним.

MySQL має ліміти розміру запиту. PHP використовує тонни пам'яті.

Кращий підхід:

Використовувати підзапит або тимчасову таблицю для великих наборів даних.

Продуктивність:

  • whereIn() з 100 елементами - нормально
  • whereIn() з 10,000 елементами - проблема
  • Підзапит - константна пам'ять

Порада: Якщо масив має більше 1000 елементів, розглянь використання підзапиту або chunking.

// ПОГАНО: Великий масив в whereIn
$userIds = range(1, 10000); // 10k ID
$users = User::whereIn('id', $userIds)->get();
// Величезний запит, високе використання пам'яті

// ДОБРЕ: Використовувати підзапит
$activeUserIds = DB::table('user_activity')
    ->where('last_login', '>', now()->subDays(30))
    ->select('user_id');

$users = User::whereIn('id', $activeUserIds)->get();

// Альтернатива: Join
$users = User::join('user_activity', 'users.id', '=',
    'user_activity.user_id')
    ->where('user_activity.last_login', '>', now()->subDays(30))
    ->select('users.*')
    ->get();

// Розділяй великі операції
$userIds = range(1, 10000);
collect($userIds)->chunk(500)->each(function ($chunk) {
    User::whereIn('id', $chunk)->update(['notified' => true]);
});
Laravel Ukraine

Laravel Ukraine

Спільнота й продуктова платформа для українських Laravel/PHP-розробників: статті, вакансії, тести, питання на співбесіди, події, 450+ відео з Laracon та каталог екосистеми в одному місці