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

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

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

3 питання

Файл приходить через $request->file(); зберігають через фасад Storage:

$request->validate([
    'avatar' => ['required', 'image', 'max:2048'], // до 2 МБ
]);

$path = $request->file('avatar')->store('avatars', 'public');
// або з випадковим унікальним іменем - store() уже так робить

$user->update(['avatar_path' => $path]);
  • store() повертає шлях для збереження в БД.
  • Публічний URL - Storage::url($path) (потребує php artisan storage:link).
  • Валідатори image, mimes:pdf,docx, max: (в КБ) убезпечують від небажаних файлів.

Докладніше в документації: Зберігання файлів

Laravel абстрагує файлові операції через фасад Storage поверх Flysystem. «Диски» (local, public, s3) налаштовуються в config/filesystems.php.

Storage::disk('s3')->put('reports/q1.pdf', $contents);
$url = Storage::disk('s3')->url('reports/q1.pdf');

$temporary = Storage::disk('s3')->temporaryUrl('reports/q1.pdf', now()->addMinutes(5));
  • php artisan storage:link створює символічне посилання public/storage → storage/app/public для публічного доступу.
  • Зміна сховища (локально ↔ S3) не вимагає переписування коду - лише конфіг.

Докладніше в документації: Зберігання файлів

Файл, покладений у storage/app, недоступний ззовні - це правильно за замовчуванням. Питання в тому, як віддати його тому, кому можна.

Що робити не варто: класти приватні файли в public/ чи публічний бакет і покладатися на те, що адресу ніхто не вгадає. Посилання розходяться, індексуються й лишаються робочими назавжди.

Спосіб 1 - віддати через контролер із перевіркою прав:

public function download(Document $document)
{
    $this->authorize('view', $document);

    return Storage::disk('private')->download($document->path, $document->name);
}

Кожне звернення проходить авторизацію. Мінус - файл іде крізь PHP, тож на великих файлах воркер зайнятий увесь час передачі.

Спосіб 2 - тимчасове підписане посилання до S3-сумісного сховища:

$url = Storage::disk('s3')->temporaryUrl($document->path, now()->addMinutes(5));

Посилання підписане й саме перестає працювати після строку. Файл віддає сховище напряму, PHP у передачі не бере участі - це те, що потрібно для великих файлів.

Спосіб 3 - підписаний маршрут, коли сховище тимчасових URL не вміє:

URL::temporarySignedRoute('documents.download', now()->addMinutes(5), ['document' => $document->id]);

Middleware signed перевіряє підпис і строк.

Про що часто забувають:

  • Спосіб 1 без authorize() перетворюється на публічний доступ через власний контролер.
  • Строк життя посилання має бути коротким: доки воно живе, ним може скористатися будь-хто, кому воно потрапило.
  • Імʼя файла від користувача не можна підставляти в шлях - Storage::putFile() генерує безпечне імʼя сам.

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