安装spatie/laravel-medialibrary需先启用模型软删除,检查并清理旧media表结构,发布迁移后执行;上传须用UploadedFile实例或addMediaFromUrl/Path;缩略图需显式定义conversions并调用performConversions;清理无主文件用medialibrary:clean命令;生产环境禁用vapor上传并合理配置存储磁盘。

安装 spatie/laravel-medialibrary 并配置数据库
必须先确保模型已启用软删除,因为 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\InteractsWithMediatrait
上传图片并关联到模型实例
上传不是靠 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'); - 若需从 URL 下载上传,用
addMediaFromUrl($url);从本地路径上传,用addMediaFromPath($path)(注意路径必须可读,且不能是相对 public 路径)
定义缩略图(Conversions)并在视图中调用
缩略图不是上传时自动触发的,必须显式调用 performConversions(),否则 getFirstMediaUrl('images', 'thumb') 返回空字符串。Laravel 的队列机制默认关闭,若未配置队列,conversions 会在响应返回前同步执行——但若上传大图且定义了多个尺寸,可能超时。
- 在模型中定义 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 就不会出现,但模型层面毫无提示——这是最常被忽略的故障点。










