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

Блог

Статті, новини, туторіали та переклади від учасників спільноти

No results.
Tips 03 липня 2026

whereHas() vs whereRelation() - швидша фільтрація

Фільтруєш користувачів які мають пости? whereHas() створює підзапит.

whereRelation() використовує join. Швидше на великих таблицях.

Різниця в продуктивності:

  • whereHas() - підзапит для перевірки кожного рядка
  • whereRelation() - одна join операція

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

Використовуй whereRelation() для простих умов на пов'язаних моделях. Використовуй whereHas() коли потрібна складна логіка або підрахунок.

Покращення Laravel 11:

whereRelation() додано в Laravel 8.57. Читабельніше ніж ручні join'и.

Порада: Для простих фільтрів зв'язків завжди віддавай перевагу whereRelation() над whereHas().

// ПОВІЛЬНО: Підзапит для кожного користувача
$users = User::whereHas('posts', function ($query) {
    $query->where('published', true);
})->get();

// ШВИДКО: Одна join операція
$users = User::whereRelation('posts', 'published', true)
    ->get();

// Декілька умов
$users = User::whereRelation('posts', 'published', true)
    ->whereRelation('posts', 'views', '>', 1000)
    ->get();

// Різні зв'язки
$users = User::whereRelation('posts', 'published', true)
    ->whereRelation('profile', 'verified', true)
    ->get();
// Коли ПОТРІБЕН whereHas() - складна логіка
$users = User::whereHas('posts', function ($query) {
    $query->where('published', true)
        ->where(function ($q) {
            $q->where('views', '>', 1000)
              ->orWhere('featured', true);
        });
})->get();

// Підрахунок зв'язків
$users = User::whereHas('posts', fn($q) =>
    $q->where('published', true), '>=', 5
)->get();

// orWhereRelation() також доступний
$users = User::whereRelation('posts', 'status', 'draft')
    ->orWhereRelation('posts', 'status', 'pending')
    ->get();
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();
Патерн Flyweight
Посібники 02 липня 2026
Патерни проєктування

Flyweight - спільні легкі об'єкти

Економить пам'ять, повторно використовуючи спільні екземпляри замість тисяч однакових. Розділення стану на внутрішній і зовнішній на прикладі кешу довідників.

17
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, можна перевіряти агентів, інструменти, векторні бази знань та чат-потоки з детермінованими результатами.

Clonio CLI
Новини 01 липня 2026

Clonio CLI: Клонування Продакшн-Бази з Анонімізацією Даних

Clonio CLI - інструмент для безпечного копіювання продакшн-бази даних у розробницьке, CI та тестове оточення з автоматичною анонімізацією персональних даних. Підтримує різні стратегії перетворення колонок, ремапінг первинних ключів та виявлення PII.

6
Tips 30 червня 2026

Lazy Collections з альтернативою cursor()

cursor() тримає з'єднання з БД відкритим. Ризиковано для довгих операцій.

lazy() використовує chunks внутрішньо. Безпечніше.

Як працює lazy():

Завантажує дані пакетами (типово 1000). Видає елементи один за одним. Закриває з'єднання між пакетами.

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

Ефективна пам'ять як cursor(). Безпека з'єднання як chunk(). Найкраще з обох світів.

Порада: Налаштуй розмір chunk з lazy(500) для точного налаштування.

// Ризиковано: З'єднання залишається відкритим
User::cursor()->each(function ($user) {
    // Довга обробка тут може таймаутнути
    $this->sendEmail($user);
});

// Краще: Chunks з lazy ітерацією
User::lazy()->each(function ($user) {
    // Безпечніше для довгих операцій
    $this->sendEmail($user);
});

// Власний розмір chunk
User::lazy(200)->each(function ($user) {
    $this->processUser($user);
});

// Працює з фільтрами
User::where('active', true)
    ->orderBy('created_at')
    ->lazy()
    ->filter(fn($user) => $user->hasOrders())
    ->each(fn($user) => $this->sendPromo($user));
Laravel WhatsApp
Новини 30 червня 2026

Laravel WhatsApp: Два Бекенди За Одним Фасадом

Новий пакет Laravel WhatsApp від Md Mostafijur Rahman дозволяє надсилати та отримувати повідомлення WhatsApp через офіційний Cloud API Meta та неофіційний веб-інтерфейс за допомогою whatsapp-web.js. Обидва варіанти працюють через єдиний фасад WhatsApp::.

8

Статті, новини та посібники про Laravel і PHP українською: релізи фреймворку, патерни, інструменти та досвід команд. Нижче - розбивка за категоріями й темами, якщо хочете звузити пошук.

Зараз опубліковано 322 матеріали від 3 авторів. Останній матеріал - 30 жовтня 2026.