必须用 composer require spatie/laravel-sluggable 安装,而非 composer install;Laravel 8 及以下需手动注册服务提供者;模型中 use Sluggable 应在 use HasFactory 之后,并声明 $fillable 包含 'slug';需配置 unique 约束及 getSlugOptions() 处理中文。

不能直接用 composer install 装 spatie/laravel-sluggable —— 它不是 Laravel 内置组件,必须显式 require。
执行 composer require spatie/laravel-sluggable 才是正确安装方式
很多人卡在第一步:看到文档写“Install with Composer”,就下意识去项目根目录运行 composer install,结果什么都没装上。这个命令只读取已存在的 composer.lock 和 vendor/,不会拉新包。
- 必须用
composer require spatie/laravel-sluggable(Laravel 9+ 可省略手动注册服务提供者) - 如果项目是 Laravel 8 或更早,装完后还要在
config/app.php的providers数组里加一行:Spatie\Sluggable\SluggableServiceProvider::class - 装完别忘了运行
php artisan vendor:publish --provider="Spatie\Sluggable\SluggableServiceProvider"—— 这步不是必须,但如果你要自定义 slug 生成逻辑(比如过滤特殊字符),就需要发布配置文件config/sluggable.php
use Sluggable 和 use HasFactory 的顺序有影响
Eloquent 模型里同时用 HasFactory 和 Sluggable trait 时,trait 加载顺序会影响属性初始化时机。常见错误是 slug 字段始终为空或生成失败。
工作流任务拆解与模型编排技能。使用场景:(1) 收到复杂工作任务需要拆解为可执行步骤,(2) 需要为不同步骤选择最合适的模型,(3) 需要跟踪工作流进度和模型使用情况,(4) 长时间任务卡住需要问题诊断和解决方案。
- 把
use Sluggable;放在use HasFactory;之后,否则$this->slug可能被工厂构造函数覆盖 - 确保模型里声明了
protected $fillable = ['title', 'slug'];—— 否则create()时slug不会被自动填充 - 别在
creating事件里手动赋值$model->slug,这会绕过 Sluggable 的生成逻辑,导致不触发generateSlug()回调
生成 slug 时中文、空格、特殊符号处理不干净?检查 sluggable 配置项
默认行为对中文支持弱,str_slug()(旧版 Laravel)或 Str::slug()(新版)本身不转拼音,遇到中文直接返回空字符串,导致 slug 为 null 或报错 Column 'slug' cannot be null。
- 在模型中重写
getSlugOptions()方法,明确指定source和method:
public function getSlugOptions() : SlugOptions
{
return SlugOptions::create()
->generateSlugsFrom('title')
->saveSlugsTo('slug')
->usingLanguage('zh'); // Laravel 10+ 支持,需安装 ext-intl
}
ext-intl,可用第三方包如 overtrue/pinyin 自定义方法:getSlugOptions() 里写 ->usingCustomSlugGenerator([App\Services\PinyinSlugGenerator::class, 'generate'])
迁移时加 slug 字段容易漏掉 unique() 约束
没加唯一索引会导致重复 slug 插入成功,后续 Route::model('post', Post::class) 找不到对应模型,抛出 ModelNotFoundException,但错误信息里完全不提 slug 问题。
- 迁移里必须写:
$table->string('slug')->unique(); - 如果表已有数据,先跑
DB::table('posts')->update(['slug' => DB::raw("LOWER(REPLACE(title, ' ', '-'))")]);补全历史记录,再加约束 - 上线前检查是否启用了
fallback_locale:当多语言内容缺失时,Sluggable 默认用app()->getLocale(),但若没设 fallback,可能生成空 slug
最常被跳过的其实是数据库字段的 unique 约束和模型 $fillable 声明——这两处一漏,后面所有 slug 逻辑都像在修漏水的桶。

















