В современной веб-разработке загрузка файлов является одной из наиболее часто используемых функций, а хранилище Laravel предоставляет интуитивно понятный способ управления хранилищем файлов.
В этом руководстве мы рассмотрим, как Laravel упростила загрузку файлов и управление файловым хранилищем с помощью Laravel Storage facade. Если вы новичок в Laravel, то это руководство познакомит вас с различными аспектами хранения файлов.
Практический пример
Чтобы попробовать примеры, представленные в этом посте, потребуется существующее приложение Laravel или новое. Я начну с нового проекта Laravel и использую composer для создания нового приложения Laravel.
composer create-project laravel/laravel DemoApp
Приведенная выше команда сгенерирует новое приложение Laravel в папке с именем DemoApp.
Откройте терминал командной строки и перейдите в папку DemoApp. Теперь выполните приведенную ниже команду.
php artisan make:auth
Эта команда создаст макет шаблона на основе bootstrap. Теперь откройте welcome.blade.php файл из resources/views
папки и замените всю разметку на приведенную ниже.
@extends('layouts.app')
@section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-header">Laravel Storage Example</div>
<div class="card-body">
<form action="{{ route('upload') }}" method="POST" role="form" enctype="multipart/form-data">
@csrf
<div class="form-group row">
<label for="file" class="col-md-4 col-form-label text-md-right">Select a file to upload</label>
<div class="col-md-6">
<input id="file" type="file" class="form-control @error('file') is-invalid @enderror" name="file" value="{{ old('file') }}">
@error('file')
<span class="invalid-feedback" role="alert">
<strong>{{ $message }}</strong>
</span>
@enderror
</div>
</div>
<div class="form-group row mb-0">
<div class="col-md-8 offset-md-4">
<button type="submit" class="btn btn-primary">Upload File</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
@endsection
В этом представлении (view) мы добавили форму с полем ввода файла и кнопкой отправки для отправки формы. Форма в этом шаблоне представления указывает маршрут с именем upload, давайте добавим этот маршрут в наш routes/web.php файл.
Route::post('/upload', 'HomeController@upload')->name('upload');
Далее мы добавим upload()
метод в HomeController.
public function upload(Request $request)
{
// All code examples will go into this method
}
Далее нам нужно обновить middleware для этого контроллера. Изменим __construct()
:
**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth');
}
На этот:
**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('auth')->except('upload');
}
Вот и все, теперь у нас есть форма с методом контроллера, где мы можем протестировать все примеры, касающиеся хранилища Laravel. Итак, давайте начнем.
Как хранилище Laravel обрабатывает файл
Laravel является одним из самых быстрорастущих фреймворков благодаря своей простоте и гибкости. Поэтому доступно множество опций для обработки загрузок файлов и форматов хранения.
Например, вы можете использовать локальную систему хранения, где все файлы будут храниться внутри самого проекта. Вы также можете использовать SFTP для передачи файлов на другие серверы или использовать облачное хранилище для хранения всех ваших файлов. Laravel предоставляет облачное хранилище Amazon S3 или Google “из коробки”.
В Laravel мы называем все эти типы хранилищ дисками, думаем о файловом хранилище и помечаем его как диск в Laravel. Если вы откроете config/filesystems.php
файл, вы узнаете все доступные диски и их конфигурации.
В config/filesystems.php
файле вы найдете два типа дисков с именами local и public. Laravel по умолчанию использует локальный диск, при этом вы можете указать тип диска, который хотите использовать при загрузке файлов.
На общедоступном диске вы обнаружите, что корневой каталог этого диска установлен в storage/app/public
, поскольку корневой каталог Laravel находится в общедоступной папке, вы должны связать storage/app/public
папку с общедоступной папкой Laravel, которая находится в корневой папке вашего проекта. Вы можете добиться этого, выполнив приведенную ниже команду artisan.
php artisan storage:link
В этом случае, если вы запустите команду внутри контейнера, то не сможете работать со ссылкой.
А если создадите ссылку из windows link будет создаваться на сетевой ресурс вне контейнера и laravel не сможет с ней работать.
Так же если по какой-то причине у вас все же возникли проблемы, как альтернатива: выполните внутри nginx контейнера консольную команду:
ln -s ../storage/app/public/ public/storage
Загрузка файлов в Laravel
Поскольку мы уже настроили игровую площадку для практики загрузки файлов, давайте продолжим и напишем некоторый код для загрузки файлов. В upload()
методе HomeController добавьте приведенную ниже строку кода:
public function upload(Request $request)
{
$path = $request->file('file')->store('files');
dd($path);
}
В приведенном выше методе мы получаем файл, загруженный через объект запроса Laravel, и используем store()
метод для сохранения загруженного файла в папке files.
Теперь, если вы запустите приложение и загрузите файл, используя форму, которую мы создали в предыдущем разделе, ваш файл будет загружен, и Laravel укажет путь к файлу.
Теперь, если вы зайдете в storage/app
папку, вы найдете новую папку с именем files, и загруженные файлы будут доступны в этой папке.
Если вы хотите присвоить имя загружаемому файлу, вы можете использовать storeAs()
метод, подобный приведенному ниже.
public function upload(Request $request)
{
$file = $request->file('file');
// Generate a file name with extension
$fileName = 'profile-'.time().'.'.$file->getClientOriginalExtension();
// Save the file
$path = $file->storeAs('files', $fileName);
dd($path);
}
После загрузки нового файла вы получите что-то вроде следующего вывода.
"files/profile-1564586486.jpg"
Загрузка нескольких файлов в Laravel
Чтобы загрузить несколько изображений одновременно, вам необходимо настроить поле ввода файла в вашей форме. Измените поле ввода с этого:
<input id="file" type="file" class="form-control @error('file') is-invalid @enderror" name="file" value="{{ old('file')}}">
К этому:
<input id="file", type="file", class="form-control @error('file') is-invalid @enderror", name="files[]", value=",{{ old('file')}}multiple ",>
Мы изменили название этого поля ввода с file
на files[]
и добавили в него атрибут multiple.
Теперь мы будем хранить несколько изображений примерно так, как показано ниже:
public function upload(Request $request)
{
$paths = [];
$files = $request->file('files');
foreach ($files as $file)
{
// Generate a file name with extension
$fileName = 'profile-'.time().'.'.$file->getClientOriginalExtension();
// Save the file
$paths[] = $file->storeAs('files', $fileName);
}
dd($paths);
}
В приведенном выше методе мы просто перебираем все файлы и сохраняем путь в $paths
массиве.
Если вы загрузите сейчас несколько файлов, вы получите результат, подобный приведенному ниже.
array:3 [▼
0 => "files/profile-1564586818.jpg"
1 => "files/profile-1564586818.jpg"
2 => "files/profile-1564586818.jpg"
]
Правила проверки при загрузке файлов
Для любого веб-приложения проверка является одной из самых важных, поскольку вы должны установить некоторые проверки, загружает ли пользователь файл нужного типа, в пределах допустимого и с правильными размерами, если это файл изображения.
Для загрузки файлов мы можем добавить правила проверки прямо в наш контроллер или вы можете использовать запрос формы Laravel.
public function upload(Request $request)
{
$validation = $request->validate([
'file' => 'required|file|image|mimes:jpeg,png,gif,jpg|max:2048'
]);
$file = $validation['file'];
// Generate a file name with extension
$fileName = 'profile-'.time().'.'.$file->getClientOriginalExtension();
// Save the file
$path = $file->storeAs('files', $fileName);
dd($path);
}
В описанном выше методе мы добавили проверку того, что загружаемый файл должен быть файлом и изображением с указанными типами расширений, а размер файла не должен превышать 2 МБ.
Полезные методы фасада Laravel Storage
Laravel Storage facade предоставляет удобный способ выполнения действий с дисками хранилища. Например, если вы хотите указать, какой диск он должен использовать при загрузке файла, вы делаете что-то вроде приведенного ниже.
Сохранить файл на определенный диск
Storage::disk('local')->put('filename.txt', 'File content goes here..');
Приведенный выше код создаст filename.txt
файл на локальном диске хранилища с предоставленным содержимым.
Получить содержимое файла
Чтобы получить содержимое файла, вы можете использовать get()
метод.
Storage::get('filename.txt');
Проверка существования файла
Чтобы проверить, существует файл или нет, мы используем exists()
метод, который вернет значение true
or false
.
Добавить в файл
Используйте приведенный ниже метод использования фасада хранилища для добавления в файл.
Storage::append('filename.txt', 'Append this text');
Скачать файл
Чтобы загрузить сохраненный файл с диска хранилища, используйте download()
метод.
Storage::download('filename.txt');
Генерация общедоступного URL
Чтобы сгенерировать общедоступную ссылку на файл, используйте приведенный ниже метод.
Storage::url('filename.txt');
Получить размер файла
Чтобы получить размер файла, используйте приведенный ниже метод.
Storage::size('filename.txt');
Удалить файл
Чтобы удалить файл, используйте delete()
метод.
Storage::delete('filename.txt');