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

Питання на співбесіді: Collections

Найпопулярніші питання з реальних Laravel/PHP співбесід для всіх рівнів

3 питання

Collection - обгортка над масивом із плавним, ланцюжковим API. Eloquent-запити повертають саме колекції.

$names = collect($users)
    ->filter(fn ($u) => $u->active)
    ->sortBy('name')
    ->map(fn ($u) => $u->name)
    ->values();

Десятки методів: map, filter, reduce, groupBy, pluck, each, sum. Код читається зрозуміліше за вкладені цикли й array_*-функції. Для дуже великих наборів є LazyCollection (на генераторах).

Докладніше в документації: Колекції

LazyCollection використовує PHP-генератори, щоб тримати в пам'яті лише один елемент за раз - критично для величезних наборів.

LazyCollection::make(function () {
    $handle = fopen('huge.csv', 'r');
    while (($line = fgets($handle)) !== false) {
        yield $line;
    }
})->filter(...)->take(100)->each(...);

З Eloquent:

User::cursor()->each(function ($user) { /* по одному рядку */ });

На відміну від звичайної Collection, методи не матеріалізують увесь набір - обчислення «ліниві» й виконуються лише при ітерації.

Докладніше в документації: Lazy Collections

Колекції зручні настільки, що ними легко почати робити роботу бази - і заплатити памʼяттю та часом.

Типова помилка:

$active = Post::all()->where('is_published', true);        // вся таблиця в памʼять
$count  = Post::all()->count();                            // теж уся таблиця
$latest = Post::all()->sortByDesc('created_at')->take(5);  // і сортування в PHP

Кожен рядок витягує всі записи, щоб потім відкинути більшість.

Те саме в базі:

$active = Post::where('is_published', true)->get();
$count  = Post::count();
$latest = Post::latest()->limit(5)->get();

Різниця не косметична: база фільтрує за індексом і повертає стільки, скільки потрібно.

Як розрізняти. Методи Builder виконуються в SQL, методи Collection - у PHP. Межа проходить там, де стоїть get(), all() чи first(): усе після них - уже PHP.

Плутанину створює однакова назва: where() є і в білдера, і в колекції. Post::where(...) фільтрує в базі, Post::all()->where(...) - у памʼяті.

Коли колекція доречна:

  • Дані вже отримані, і потрібне ще одне групування чи перетворення - другий запит дорожчий.
  • Логіка не виражається в SQL: складна умова на PHP, робота з обʼєктами-значеннями.
  • Набір свідомо малий - десятки рядків, де різниці немає.

Коли ні: фільтрація, підрахунок, сортування й обмеження на таблиці, розмір якої росте. Це робота бази.

Проміжний варіант - lazy(): обхід пачками з синтаксисом колекції, коли обробити треба всі рядки, але тримати їх у памʼяті не можна.

Докладніше в документації: Колекції