直接运行 composer require spatie/laravel-medialibrary 即可,Composer 会自动选择兼容当前 Laravel 和 PHP 版本的最新稳定版;手动指定版本易导致不兼容,尤其 Laravel 11 必须使用 v10+ 才支持软删除字段自定义。

直接运行 composer require spatie/laravel-medialibrary 就行,别加版本号硬指定
新版(v10+)已默认适配 Laravel 10–11 和 PHP 8.1+,不填版本号会让 Composer 自动选兼容当前环境的最新稳定版。手动写 ^10.0 或 ^9.0 容易卡在旧版,尤其当你用的是 Laravel 11 —— v9 不支持模型软删除字段名自定义,而 v10+ 才修复了这个限制。
装完立刻检查 vendor/spatie/laravel-medialibrary/src/MediaLibraryServiceProvider.php 是否存在,不存在说明安装失败,大概率是网络中断或 composer.lock 冲突,删掉 vendor 和 composer.lock 重试。
迁移前必须确认模型启用了软删除
Media 模型依赖 deleted_at 字段做关联清理,如果目标模型(比如 AppModelsPost)没启用软删除,上传后删模型不会自动删媒体文件,残留文件越积越多。
- 在模型里加
use SoftDeletes;,并确保$dates = ['deleted_at'];或 Laravel 9+ 的protected $casts = ['deleted_at' => 'datetime']; - 如果表里没有
deleted_at字段,补一个:php artisan make:migration add_deleted_at_to_posts_table --table=posts,然后在迁移里写$table->softDeletes(); - 旧项目若已存在
media表(v8 或更早),别直接跑php artisan migrate—— 表结构不兼容,先手动删掉旧迁移、清空media表,再发布新迁移
发布迁移和配置时注意 tag 名称差异
官方文档和社区教程 tag 名经常混用,但实际能用的只有两个标准值:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 发迁移:必须用
--tag="medialibrary-migrations"(不是migrations,也不是medialibrary::migrations) - 发配置:用
--tag="medialibrary-config"(不是config,否则会覆盖你自己的config/app.php) - 执行顺序不能错:先
vendor:publish --tag="medialibrary-migrations",再migrate,最后才考虑配medialibrary-config
如果执行后 database/migrations 下没生成文件,说明 tag 错了,或者 ServiceProvider 没被正确识别 —— 检查 composer.json 的 autoload 是否包含 "psr-4": {"Spatie\": "vendor/spatie/laravel-medialibrary/src/"}(通常自动处理,但某些低版本 Composer 会漏)
上传文件必须传 UploadedFile 实例或路径字符串,不能传 base64
addMedia() 只接受三种输入:UploadedFile 对象(来自 $request->file('xxx'))、本地绝对路径(/var/www/storage/file.jpg)、远程 URL(https://...)。传 base64 字符串会直接报 Call to a member function getPathname() on string。
- 表单上传:用
$model->addMedia($request->file('avatar'))->toMediaCollection('avatars') - 后台批量导入:用
$model->addMediaFromUrl('https://example.com/photo.jpg')->toMediaCollection('imported') - 想从 base64 转,得先解码保存成临时文件,再传路径:
file_put_contents($tmpPath, base64_decode($base64String)),然后addMedia($tmpPath)
磁盘配置容易被忽略:默认走 public 磁盘,但生产环境建议单独配 media 磁盘并加入 .gitignore,否则上传的文件会被提交进仓库。

















