В 11-ом уроке мы погрузимся в работу с файлами и хранилищем в Laravel. Это важная тема, ведь почти каждое веб-приложение так или иначе взаимодействует с файлами, загружает аватарки, сохраняет документы или обрабатывает изображения. В этом уроке я расскажу, как правильно работать с файлами, куда их сохранять и как обеспечить к ним безопасный доступ.
Загрузка файлов через формы
Первое, с чем мы сталкиваемся при работе с файлами, это их загрузка через HTML-формы. В Laravel это делается просто, но есть нюансы, о которых важно знать.
Шаг 1: Создание формы для загрузки
Допустим, мы хотим создать форму для загрузки аватара пользователя. Вот как это выглядит в Blade:
<!-- resources/views/profile/avatar.blade.php --> <form method="POST" action="{{ route('avatar.upload') }}" enctype="multipart/form-data"> @csrf <input type="file" name="avatar" required> <button type="submit">Загрузить аватар</button> </form>
Атрибут enctype="multipart/form-data"
обязателен для загрузки файлов. Без него файл не будет отправлен на сервер.
Шаг 2: Обработка файла в контроллере
Создадим контроллер AvatarController
и метод upload
:
php artisan make:controller AvatarController
В методе upload
мы получим файл из запроса:
// app/Http/Controllers/AvatarController.php public function upload(Request $request) { // Валидация файла $request->validate([ 'avatar' => 'required|file|image|max:2048', // Максимум 2 МБ ]); // Получаем файл $file = $request->file('avatar'); // Сохраняем файл (об этом ниже) $path = $file->store('avatars'); // Сохраняем путь к файлу в БД (пример) auth()->user()->update(['avatar_path' => $path]); return redirect()->back()->with('success', 'Аватар успешно загружен!'); }
Сохранение файлов в storage/app
Laravel использует систему хранилищ (Storage) для работы с файлами. По умолчанию файлы сохраняются в storage/app
. Это безопасно, так как эта папка недоступна извне (в отличие от public
).
Как сохранить файл?
Используйте метод store()
, как в примере выше, или явно укажите диск:
$path = $file->store( 'avatars', // Папка внутри storage/app 'local' // Имя диска (по умолчанию 'local') );
Структура storage/app
storage/app/avatars
— ваши загруженные файлы.storage/app/public
— файлы, которые должны быть доступны публично (например, через браузер).storage/app/private
— закрытые файлы (требуют аутентификацию).
Создание символической ссылки (storage:link)
Файлы в storage/app
по умолчанию недоступны извне. Чтобы сделать их публичными, нужно создать символическую ссылку из public/storage
в storage/app/public
.
Как это сделать?
Запустите команду:
php artisan storage:link
Теперь все файлы, сохраненные в storage/app/public
, будут доступны по URL:
http://ваш-сайт/storage/имя-файла.jpg
Если вы работаете на Windows, убедитесь что ваша система поддерживает символические ссылки или используйте WSL.
Генерация URL для файлов
Чтобы получить URL файла, используйте фасад Storage
:
use Illuminate\Support\Facades\Storage; // Для файла в storage/app/public $url = Storage::url('имя-файла.jpg'); // Вернет: /storage/имя-файла.jpg // Для файла в storage/app/avatars (не в public!) $url = Storage::disk('local')->url('avatars/файл.jpg'); // Но это сработает только, если настроен соответствующий маршрут.
Файлы вне storage/app/public
не будут доступны через браузер, если вы не создадите для них специальный маршрут.
Практические задачи
Задача 1: Загрузка аватара
- Создайте форму для загрузки аватара.
- Реализуйте валидацию: только изображения до 2 МБ.
- Сохраните файл в
storage/app/public/avatars
. - Выведите загруженный аватар на странице профиля.
Решение:
// В контроллере $path = $request->file('avatar')->store('public/avatars'); // В Blade <img src="{{ Storage::url(str_replace('public/', '', $path)) }}" alt="Аватар">
Задача 2: Создайте галерею изображений
Позвольте пользователям загружать несколько изображений и выводите их в виде сетки.
Подсказка:
// Для загрузки нескольких файлов $files = $request->file('images'); foreach ($files as $file) { $file->store('public/gallery'); }
Частые ошибки
- Забыли
enctype="multipart/form-data"
— файл не загрузится. - Пытаются получить доступ к
storage/app
напрямую — используйтеstorage:link
. - Не проверяют тип файла — злоумышленник может загрузить скрипт вместо изображения.
Хотите освоить Laravel быстрее? Перейти к полному курсу по Laravel для начинающих