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

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

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

3 питання

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

php artisan make:filament-resource Vacancy --generate

Команда створює клас ресурсу, сторінки List/Create/Edit, а форму й таблицю виносить в окремі файли (Schemas/VacancyForm.php, Tables/VacancyTable.php). Прапорці --embed-schemas і --embed-table лишають їх усередині класу ресурсу.

Дві головні частини - форма й таблиця:

public static function form(Schema $schema): Schema
{
    return $schema->components([
        TextInput::make('title')
            ->required()
            ->maxLength(255),
        Select::make('level')
            ->options(VacancyLevel::class)
            ->required(),
        Toggle::make('is_published'),
    ]);
}

public static function table(Table $table): Table
{
    return $table
        ->columns([
            TextColumn::make('title')->searchable()->sortable(),
            TextColumn::make('company.name')->label('Компанія'),
            IconColumn::make('is_published')->boolean(),
        ])
        ->filters([
            SelectFilter::make('level')->options(VacancyLevel::class),
        ]);
}

Що це дає без додаткового коду: список із пошуком, сортуванням і пагінацією, форми створення й редагування з валідацією, масові дії, фільтри.

На чому побудовано: Livewire відповідає за реактивність без написання JS, Alpine - за дрібні взаємодії в браузері, Tailwind - за оформлення. Тому Filament - це PHP-код, а не окремий фронтенд-застосунок.

Що варто знати одразу: форма й таблиця - це звичайні PHP-масиви обʼєктів, тож видимість поля, опції списку чи доступність дії задаються замиканнями й можуть залежати від користувача та стану запису.

Filament - фреймворк Server-Driven UI для Laravel: інтерфейси (адмінки, панелі) описуються на PHP через структуровані об'єкти, а не верстку.

public static function form(Schema $schema): Schema
{
    return $schema->components([
        TextInput::make('title')->required(),
        Select::make('status')->options(Status::class),
    ]);
}
  • Побудований на Livewire, Alpine.js і Tailwind CSS.
  • Будівельні блоки: Resources, Forms, Tables, Actions, Infolists, Widgets.
  • Компоненти ініціалізуються статичними make()-методами; динамічні значення задаються замиканнями з утилітами Get/Set.

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

N+1 у колонках. Колонка зі звʼязком робить запит на рядок:

TextColumn::make('company.name')   // + 1 запит на кожен рядок

Лікується модифікацією запиту таблиці:

public static function getEloquentQuery(): Builder
{
    return parent::getEloquentQuery()->with(['company', 'technologies']);
}

Лічильники. ->counts('vacancies') замість завантаження всієї колекції заради count().

Дорогі обчислення в state(). Замикання виконується для кожного рядка, тож звернення до бази всередині - те саме N+1, лише написане інакше.

Сортування й пошук за звʼязком роблять join, і без індексу на зовнішньому ключі це помітно:

TextColumn::make('company.name')
    ->searchable()      // where по приєднаній таблиці
    ->sortable()

Що ще сповільнює адмінку:

  • ->paginated([10, 25, 50, 'all']) з опцією all на великій таблиці вивантажує все в памʼять одним кліком користувача.
  • Глобальний пошук по багатьох ресурсах виконує запит на кожен зареєстрований ресурс.
  • Мініатюри без кешу: ImageColumn, що генерує прев'ю на льоту, робить це для кожного рядка.
  • Опції Select без ->searchable() вивантажують усі записи довідника у форму.

Як шукати причину: Debugbar або Telescope на сторінці ресурсу покажуть кількість запитів. Таблиця на 25 рядків має вкладатися в одиниці запитів; десятки - ознака незавантаженого звʼязку.