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

Питання на співбесіді рівня Junior

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

40 питань

Soft Deletes - «м'яке» видалення: запис не стирається фізично, а отримує мітку часу в колонці deleted_at. Такі записи автоматично виключаються з усіх запитів.

class Post extends Model
{
    use SoftDeletes; // + $table->softDeletes() у міграції
}

$post->delete(); // ставить deleted_at
Post::withTrashed()->get(); // включно з видаленими
$post->restore(); // відновити
$post->forceDelete(); // видалити назавжди

Навіщо: можливість відновлення, аудит, збереження посилальної цілісності.

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

Через об'єкт Request, який Laravel автоматично впроваджує в метод контролера:

public function store(Request $request)
{
    $name = $request->input('name', 'default');
    $email = $request->string('email'); // типізовані хелпери
    $active = $request->boolean('active');
    $all = $request->only(['name', 'email']);
}

Динамічний доступ $request->name теж працює, але його уникають через можливі колізії з параметрами маршруту. Для файлів - $request->file('avatar'), для перевірки наявності - $request->has('key').

Докладніше в документації: HTTP-запити

Artisan - CLI Laravel. Він прискорює рутину: генерацію класів, міграції, очищення кешу, запуск черг тощо.

php artisan list # усі команди
php artisan make:model Post -mfsc # модель + міграція, фабрика, сидер, контролер
php artisan migrate
php artisan queue:work
php artisan tinker # інтерактивна REPL-консоль

Під капотом Artisan побудований на Symfony Console. Можна писати власні команди через make:command.

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

Сесії зберігають стан користувача між запитами. Laravel дає єдиний API поверх різних драйверів (file, cookie, database, redis), що налаштовуються в config/session.php.

session(['cart_id' => 42]); // записати
$id = session('cart_id');   // прочитати
$request->session()->forget('cart_id'); // видалити
session()->flush();         // очистити все

Для продакшену з кількома серверами зазвичай обирають redis або database, щоб сесія була спільною між інстансами.

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

Flash Data - дані, що живуть у сесії лише до наступного запиту й потім автоматично видаляються. Класичне застосування - повідомлення про результат дії після редиректу.

return redirect('/dashboard')->with('status', 'Профіль оновлено!');
@if (session('status'))
    <div class="alert">{{ session('status') }}</div>
@endif

Під капотом - session()->flash('key', $value). Метод reflash() продовжує життя flash-даних ще на один запит.

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

У сучасному Laravel ассети збирає Vite. У шаблоні підключають директивою @vite:

@vite(['resources/css/app.css', 'resources/js/app.js'])

Під час розробки (npm run dev) Vite віддає файли з hot-reload; на продакшені (npm run build) - зібрані файли з хешами в імені для cache busting.

Для статичних файлів із public/ використовують хелпер asset('images/logo.png').

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

Вони перетворюють атрибути моделі «на льоту». У сучасному Laravel обидва описуються одним методом, що повертає Attribute:

protected function name(): Attribute
{
    return Attribute::make(
        get: fn (string $value) => ucfirst($value), // accessor (читання)
        set: fn (string $value) => strtolower($value), // mutator (запис)
    );
}
  • Accessor форматує значення при отриманні ($user->name).
  • Mutator форматує значення перед збереженням у БД.

Корисно для форматування, нормалізації або роботи з Value Objects.

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

Достатньо викликати paginate() замість get() - Laravel сам читає номер сторінки з query-параметра ?page=:

$posts = Post::latest()->paginate(15);
@foreach ($posts as $post) ... @endforeach
{{ $posts->links() }}   {{-- кнопки навігації --}}
  • paginate() рахує загальну кількість (показує «сторінка X з Y»).
  • simplePaginate() - лише «вперед/назад», без COUNT(*), швидше на великих таблицях.
  • cursorPaginate() - курсорна пагінація, найефективніша для нескінченного скролу.

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

Route Model Binding автоматично резолвить параметр маршруту в екземпляр моделі - не треба вручну робити findOrFail().

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

// $post - вже знайдена модель
public function show(Post $post)
{
    return view('posts.show', compact('post'));
}

За замовчуванням пошук іде за id. Прив'язати за іншим стовпцем: {post:slug}. Якщо запис не знайдено - автоматично 404.

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

Згенерувати клас і описати логіку в handle():

php artisan make:command SendReports
class SendReports extends Command
{
    protected $signature = 'reports:send {--month=}';
    protected $description = 'Розіслати місячні звіти';

    public function handle(): int
    {
        $this->info('Відправка...');
        return self::SUCCESS;
    }
}

Аргументи й опції описуються в $signature. Команду можна запускати вручну або ставити в розклад через Schedule::command('reports:send')->monthly().

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

Factory (фабрика) генерує фейкові дані моделей через Faker. Незамінна в тестах і сидерах.

class PostFactory extends Factory
{
    public function definition(): array
    {
        return [
            'title' => fake()->sentence(),
            'body'  => fake()->paragraphs(3, true),
        ];
    }
}
Post::factory()->count(10)->create(); // 10 записів у БД
Post::factory()->published()->make(); // стан + без збереження

«Стани» (states) дозволяють описати варіації, наприклад ->published() чи ->trashed().

Докладніше в документації: Фабрики моделей

Локалізація дає багатомовність. Рядки перекладів лежать у lang/{locale} (наприклад, lang/uk/messages.php або JSON-файли).

// lang/uk/messages.php
return ['welcome' => 'Ласкаво просимо, :name'];
{{ __('messages.welcome', ['name' => $user->name]) }}
  • app()->setLocale('uk') перемикає мову (зазвичай у middleware).
  • trans_choice() обирає форму за кількістю (1 яблуко / 2 яблука / 5 яблук).

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

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 (на генераторах).

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

Лист описується класом Mailable, шаблон - Blade або Markdown.

php artisan make:mail WelcomeEmail --markdown=emails.welcome
Mail::to($user)->send(new WelcomeEmail($user));

Налаштування транспорту (SMTP, Mailgun, SES, log) - у config/mail.php та .env. Реалізувавши ShouldQueue на Mailable, відправку можна винести в чергу, щоб не блокувати запит.

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

Query Builder - плавний інтерфейс для побудови SQL-запитів без написання рядкового SQL. Працює з усіма підтримуваними СУБД і захищає від SQL-ін'єкцій через підготовлені вирази.

$users = DB::table('users')
    ->where('votes', '>', 100)
    ->orderBy('name')
    ->limit(10)
    ->get();

Повертає прості об'єкти stdClass. Eloquent побудований поверх Query Builder, тож ті самі методи (where, join, orderBy) доступні і на моделях.

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