Chuyển đến nội dung chính

Lesson 8: File Storage & Media

Filesystem abstraction (local, S3, GCS). File upload, validation. Spatie Media Library. Image manipulation (Intervention Image). Temporary URLs, streaming downloads.

💻 Programming — Lesson 8 Lesson 8: File Storage & Media

Laravel: From Basics to Advanced

Part 2: Database & Validation

xdev.asia

1. Filesystem

use Illuminate\Support\Facades\Storage;

// Upload
$path = $request->file('avatar')->store('avatars', 'public');

// S3 config (config/filesystems.php)
's3' => [
    'driver' => 's3',
    'key' => env('AWS_ACCESS_KEY_ID'),
    'secret' => env('AWS_SECRET_ACCESS_KEY'),
    'region' => env('AWS_DEFAULT_REGION'),
    'bucket' => env('AWS_BUCKET'),
],

// Sử dụng
Storage::disk('s3')->put('path/file.jpg', $contents);
$url = Storage::disk('s3')->url('path/file.jpg');
$tempUrl = Storage::disk('s3')->temporaryUrl('path/file.jpg', now()->addMinutes(30));

2. File Upload

public function upload(Request $request)
{
    $request->validate([
        'file' => 'required|file|max:10240', // 10MB
        'image' => 'nullable|image|dimensions:min_width=100,max_width=2000',
    ]);

    $file = $request->file('file');
    $path = $file->storeAs(
        'uploads/' . now()->format('Y/m'),
        $file->hashName(),
        'public'
    );

    return response()->json(['url' => Storage::url($path)]);
}

3. Spatie Media Library

composer require spatie/laravel-medialibrary
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="medialibrary-migrations"
use Spatie\MediaLibrary\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;

class Product extends Model implements HasMedia
{
    use InteractsWithMedia;

    public function registerMediaConversions(?Media $media = null): void
    {
        $this->addMediaConversion('thumb')
            ->width(300)->height(300)
            ->sharpen(10);

        $this->addMediaConversion('preview')
            ->width(800)->height(600);
    }

    public function registerMediaCollections(): void
    {
        $this->addMediaCollection('images')->useDisk('s3');
        $this->addMediaCollection('documents')->singleFile();
    }
}

// Sử dụng
$product->addMediaFromRequest('image')->toMediaCollection('images');
$url = $product->getFirstMediaUrl('images', 'thumb');

4. Intervention Image

use Intervention\Image\Laravel\Facades\Image;

$image = Image::read($request->file('photo'))
    ->resize(800, null, function ($constraint) {
        $constraint->aspectRatio();
        $constraint->upsize();
    })
    ->toWebp(quality: 80);

Storage::put('photos/optimized.webp', $image);

Next article: Authentication — Sanctum & Fortify.