安装spatie/laravel-medialibrary需先启用模型软删除,检查并清理旧media表结构,发布迁移后执行;上传须用UploadedFile实例或addMediaFromUrl/Path;缩略图需显式定义conversions并调用performConversions;清理无主文件用medialibrary:clean命令;生产环境禁用vapor上传并合理配置存储磁盘。
必须先确保模型已启用软删除,因为 Media 模型默认依赖 deleted_at 字段做关联清理。运行迁移前检查 media 表是否已存在——如果之前装过旧版(v8 或更早),表结构不兼容,直接 php artisan migrate 会报错。
composer require spatie/laravel-medialibrary
php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="migrations"
create_media_table.php 迁移(如有),再运行 php artisan migrate
App\Models\Post)中使用 Spatie\MediaLibrary\HasMedia 和 Spatie\MediaLibrary\InteractsWithMedia trait上传不是靠 model->addMedia() 直接处理文件流,而是必须传入一个可读的路径或 Illuminate\Http\UploadedFile 实例。常见错误是传字符串路径却没加 @ 前缀,或用 file_get_contents() 结果直接传——这会触发「Invalid argument supplied for foreach()」异常。
$request->file('image') 是合法输入;$request->input('image') 是字符串,不能直接传给 addMedia()
use Illuminate\Http\UploadedFile;
$uploadedFile = $request->file('image');
$post->addMedia($uploadedFile)->toMediaCollection('images');addMediaFromUrl($url);从本地路径上传,用 addMediaFromPath($path)(注意路径必须可读,且不能是相对 public 路径)缩略图不是上传时自动触发的,必须显式调用 performConversions(),否则 getFirstMediaUrl('images', 'thumb') 返回空字符串。Laravel 的队列机制默认关闭,若未配置队列,conversions 会在响应返回前同步执行——但若上传大图且定义了多个尺寸,可能超时。
public function registerMediaConversions(Media $media = null): void
{
$this->addMediaConversion('thumb')
->width(120)
->height(90)
->sharpen(10);
$this->addMediaConversion('webp')
->format('webp')
->quality(80);
}$post->getFirstMediaUrl('images', 'thumb') 返回完整 URL;$post->getFirstMedia('images')?->getUrl('thumb') 效果相同getUrl('nonexistent') 不报错,只返回原图 URL;调试时可用 $media->hasGeneratedConversion('thumb') 判断是否已生成medialibrary 不自动删原始文件或缩略图,即使你调用 $model->clearMediaCollection('images'),也只是解除关联,文件仍留在 storage/app/media 下。长期运行后容易堆积 GB 级无主文件。
php artisan medialibrary:clean(删无主 media 记录对应文件)和 php artisan medialibrary:regenerate(重做指定 conversion)'enable_vapor_uploads' => false(默认为 true),否则在非
Vapor 环境下上传会卡住或报 VaporClientException
STORAGE_DISK=public 改为 local,并通过 nginx alias 指向 storage/app/public,避免 public 目录被写满影响其他静态资源缩略图生成逻辑藏在后台 job 里,一旦队列挂掉或失败,conversion 就不会出现,但模型层面毫无提示——这是最常被忽略的故障点。