Laravel如何实现模型的全局作用域?(Global Scope示例)

4次阅读

全局作用域用于为模型所有查询自动添加约束条件,如状态过滤;需实现Scope接口并重写apply方法,在模型boot中用addGlobalScope注册,可用withoutGlobalScopes等方法临时取消。

Laravel如何实现模型的全局作用域?(Global Scope示例)

laravel 中,全局作用域(Global Scope)用于为模型的所有查询自动添加约束条件,比如软删除、多租户隔离、状态过滤等。它比在每个查询中手动加 where 更安全、更统一。

定义全局作用域类

创建一个实现 IlluminatedatabaseEloquentScope 接口的类,重写 apply() 方法,在这里编写你要注入的查询逻辑:

namespace AppScopes;  use IlluminateDatabaseEloquentBuilder; use IlluminateDatabaseEloquentModel; use IlluminateDatabaseEloquentScope;  class ActiveScope implements Scope {     public function apply(Builder $builder, Model $model)     {         $builder->where('status', 'active');     } }

在模型中注册全局作用域

在模型的 boot() 方法中调用 addGlobalScope() 注册作用域:

namespace AppModels;  use AppScopesActiveScope; use IlluminateDatabaseEloquentModel;  class Post extends Model {     protected static function boot()     {         parent::boot();          static::addGlobalScope(new ActiveScope());     } }

此后所有对 Post 的查询(如 Post::all()Post::find(1))都会自动加上 WHERE status = 'active'

临时取消全局作用域

某些场景下需要绕过全局作用域,比如后台管理或数据迁移,可用以下方式:

Laravel如何实现模型的全局作用域?(Global Scope示例)

Moshi Chat

法国AI实验室Kyutai推出的端到端实时多模态AI语音模型,具备听、说、看的能力,不仅可以实时收听,还能进行自然对话。

Laravel如何实现模型的全局作用域?(Global Scope示例) 160

查看详情 Laravel如何实现模型的全局作用域?(Global Scope示例)

  • Post::withoutGlobalScopes()->get():移除全部全局作用域
  • Post::withoutGlobalScope(ActiveScope::class)->get():仅移除指定作用域
  • Post::withTrashed()->get()(如果用了软删除):这是 Laravel 内置的特例,本质也是全局作用域

匿名全局作用域(适合简单逻辑)

不想单独建类?可以直接传闭包

protected static function boot() {     parent::boot();      static::addGlobalScope('active', function (Builder $builder) {         $builder->where('status', 'active');     }); }

注意:用字符串名注册时,取消要用同名,例如 withoutGlobalScope('active')

基本上就这些。全局作用域不复杂但容易忽略——关键在统一性和可维护性,别滥用,也别漏掉清除场景。

text=ZqhQzanResources