Загрузка файлов Laravel
Работа с файлами в любом приложении является важной частью любой системы. Laravel предоставляет файловую систему, из которой мы можем взаимодействовать с файлами; загрузки файлов, их хранения или извлечения. В этой статье мы рассмотрим, как загружать и сжимать файлы в Laravel перед их сохранением.
Как загружать файлы в Laravel?
Чтобы загрузить файлы в Laravel, мы можем выполнить следующие шаги:
Шаг 1: Создайте проект Laravel
Мы можем использовать команду Laravel new или composer
laravel new test
Или
composer create-project laravel/laravel test
Шаг 2. Добавьте аутентификацию
На этом этапе мы можем использовать Laravel breeze для проверки подлинности и выполнения всех других необходимых требований, таких как сброс пароля и логика подтверждения электронной почты.
composer require laravel/breeze
Шаг 3: Добавьте модель и миграцию
Следующим шагом является создание файла миграции, который будет содержать имя файла и папку. Мы можем использовать artisan для создания модели и файла миграции.
php artisan make:model Files -m
Флаг -m создает файл миграции для файловой модели . Мы можем добавить следующую логику к модели
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Files extends Model { use HasFactory; protected $fillable = ['path']; }
Затем мы можем указать столбцы в таблице файлов
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('files', function (Blueprint $table) { $table->id(); $table->string('path'); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('files'); } };
Шаг 4. Создайте общий Trait загрузки файлов
Trait помогает нам повторно использовать код в нескольких классах. Этот trait будет содержать логику для загрузки файла , переименования файла , сохранения файлов в папках, указанных пользователем , и удаления файлов из хранилища.
Например, в системе электронной коммерции мы можем захотеть разделить изображения на папки; Основные изображения, второстепенные изображения, баннеры и т. д.
Для этого мы будем использовать класс Illuminate\Http\UploadedFile для работы с файлами.
Мы также можем сделать трейт пригодным для использования с любым внешним диском, таким как Amazon S3.
Laravel поддерживает локальное хранилище файлов и Amazon S3 из коробки. Если вы хотите использовать Google Cloud Storage в качестве хранилища, вы можете рассмотреть возможность использования этого пакета.
В любом случае, какой бы сервис хранения вы ни решили использовать, трейт должен иметь возможность обрабатывать его без добавления каких-либо дополнительных реализаций.
Мы можем создать папку App\Traits в папке App, которая будет содержать все наши черты.
<?php namespace App\Traits; use Illuminate\Support\Str; use Illuminate\Http\UploadedFile; use Illuminate\Support\Facades\Storage; trait Upload { public function UploadFile(UploadedFile $file, $folder = null, $disk = 'public', $filename = null) { $FileName = !is_null($filename) ? $filename : Str::random(10); return $file->storeAs( $folder, $FileName . "." . $file->getClientOriginalExtension(), $disk ); } public function deleteFile($path, $disk = 'public') { Storage::disk($disk)->delete($path); } }
Чтобы сжать изображения при загрузке, мы можем использовать один из пакетов Spatie.
composer require spatie/laravel-image-optimizer
Мы можем автоматически сжимать изображения при загрузке, тем самым уменьшая размер их файлов перед загрузкой в хранилище. Чтобы настроить его, нам сначала нужно зарегистрировать его как промежуточное ПО маршрута в файле app/Http/Kernel.php .
// app/Http/Kernel.php protected $routeMiddleware = [ 'optimizeImages' => \Spatie\LaravelImageOptimizer\Middlewares\OptimizeImages::class, ];
Позже мы назначим промежуточное ПО маршруту загрузки файлов.
Шаг 5. Обработка загрузки файлов с помощью контроллера
Следующим шагом будет получение файлов через POST-запрос. Для этого мы будем использовать метод store в контроллере загрузки файлов.
Мы также можем проверить проверки, чтобы убедиться, что загруженные файлы имеют правильный тип и являются разрешенными файлами.
Путь к файлу также хранится в таблице файлов. Путь к файлу возвращается из нашего трейта после того, как он переименовал загружаемый файл. Формат пути к файлу будет следующим : Папка/имя файла и расширение, т.е. Products/HIDvPbozwW.png
<?php namespace App\Http\Controllers; use App\Models\Files; use App\Traits\Upload; use Illuminate\Http\Request; class FilesController extends Controller { use Upload; public function store(Request $request) { if ($request->hasFile('file')) { $path = $this->UploadFile($request->file('file'), 'Products'); Files::create([ 'path' => $path ]); return redirect()->route('files.index')->with('success', 'File Uploaded Successfully'); } } }
Пути к файлам в базе
Шаг 6: Добавьте маршрут
Мы можем добавить маршрут в файл route/web.php . Мы можем использовать промежуточное программное обеспечение, которое мы создали ранее в нашем маршруте.
Route::post('upload-files', [FileController::class,'store'])->middleware('optimizeImages');
Шаг 7: Добавьте пользовательский интерфейс загрузки файлов
Мы можем создать файл просмотра и добавить форму загрузки файла
Форма загрузки файла
Шаг 8. Добавьте ссылку на хранилище (необязательно)
Файлы, загруженные с использованием общедоступного диска, всегда хранятся в папке storage/app/public . Мы можем использовать команду storage:link для создания символической ссылки на общую папку.
php artisan storage:link
Шаг 9: Просмотр загруженных файлов
Как только файлы будут загружены в предпочитаемое вами хранилище, вы сможете просмотреть файл. Если вы используете общую папку, вы можете использовать вспомогательную функцию ресурса или вспомогательную функцию public_path , чтобы вернуть путь к файлу. Если вы используете стороннюю систему хранения, такую как s3 или хранилище Google Cloud, вы можете использовать фасад хранилища.
Использование общей папки
asset('storage/'.$file->path)
Использование S3 или GCS
use Illuminate\Support\Facades\Storage; Storage::disk('s3')->url($file->path)
Затем вы можете добавить путь в качестве источника изображения и отобразить их в своем приложении.
<img src="{{asset('storage/'.$file->path)}}" alt="file name"> //or <img src="{{$file->path}}" alt="file name">
Показать файлы
Как обновить файлы в Laravel?
По умолчанию нет встроенного способа обновить файлы/изображения с помощью стандартного запроса PUT или PATCH, основанного на этой проблеме . Поэтому нам нужно искать другой способ сделать это. Мы могли бы использовать запрос POST, но затем удалить предыдущий файл, если он существует, а затем загрузить новый файл и обновить путь к файлу в базе данных.
public function update_file(Request $request) //POST { //get the file id and retrieve the file record from the database $file_id = $request->input('file_id'); $file = Files::where('id', $file_id)->first(); //check if the request has a file if ($request->hasFile('file')) { //check if the existing file is present and delete it from the storage if (!is_null($file->path)) { $this->deleteFile($file->path); } //upload the new file $path = $this->UploadFile($request->file('file'), 'Products'); } //upadate the file path in the database $file->update(['path' => $path]); //redirect with the success message return redirect()->back()->with('success', 'File Updated Successfully'); }
Затем мы можем определить маршрут для обновления файла.
Route::post('update-file', [FilesController::class, 'update_file'])->middleware('optimizeImages');
Как загрузить несколько файлов и изображений в Laravel?
Это довольно легко. Мы можем повторно использовать наш трейт и использовать цикл foreach для загрузки и сохранения пути в базе данных.
Сначала мы обновим файловый контроллер, чтобы разрешить несколько файлов.
<?php namespace App\Http\Controllers; use App\Models\Files; use App\Traits\Upload; use Illuminate\Http\Request; class FilesController extends Controller { use Upload; public function store(Request $request) { $file_details = []; //check if request has files if ($request->hasFile('files')) { // loop through each file and upload foreach ($request->file('files') as $key => $file) { //Upload to Storage $path = $this->UploadFile($file, 'Products'); //reformat the file details array_push($file_details, [ 'path' => $path, ]); } //add each file details to database foreach ($file_details as $key => $value) { Files::create($value); } } } }
Метод store теперь позволяет загружать несколько файлов.
Как изменить размер файлов в Laravel?
Вы можете изменить размер файлов перед их сохранением с помощью пакета Intervention Image . Этот пакет может помочь вам изменить размер изображений перед их сохранением.
use Intervention\Image\Facades\Image; Image::make($file->path)->resize(200, 200);
Заключение
Работа с файлами и изображениями может быть сложной задачей в любом приложении, но Laravel позволяет легко работать с несколькими службами хранилища, используя их встроенные API и другие сторонние пакеты.