1. 本地作用域
      1. 很多情况下,我们在数据查找是有一部分条件会被重复且大量使用
      2. 而这个条件,可能只是在这个模型对应的数据包使用,别的表并不使用
      3. 那么这种情况,可以使用本地作用域的方式,将常用的SQL封装起来;
      4. 比如:用户模块中,我们大量查询性别为男,且其他条件的SQL

    $users = User::where(‘gender’, ‘女’)
    ->where(‘price’,’>’,’90’)
    ->get();
    PS: 我们可以将性别为男这个片段,封装成一个单独的方法,然后统一在这个模型下调用:

    //App\Http\Models;
    //本地作用域,搜索自动添加为”男”的条件
    //语法:scope开头,后面名称尽可能包含语义
    public function scopeGenderMale($query){
    $query->where(‘gender’, ‘女’);
    }
    //当然,如果赶紧单词太长,直接gm()也行
    $users = User::genderMale()
    ->where(‘price’, ‘>’, 90)
    ->get();
    e. 上面的方法比较死板,适合简单粗暴,如果想要灵活多变,支持传递参数
    //参数可以是1个或多个
    $users = User::gender(‘女’, 0)
    ->where(‘price’,’>’,90)
    ->get();
    //参数2和3,接受控制器传递过来的1,2
    public function scopeGender($query, $value, $value2 = 1){
    $query->where(‘gender’, $value)->where(‘status’, $value2);
    }

    1. 全局作用域
      1. 全局作用域,顾名思义就是在任意地方都可以有效的封装条件:
      2. 比如有个需求,不管在哪里操作,总是显示status为1的用户
      3. 首先在app目录下创建一个用于全局作用域的目录:Scopes:
      4. 创建一个用于设置status为1的全局作用域的类,它需要实现scope接口

    namespace App\Scopes;

    //这里引用代码自动生成
    use Illuminate\Database\Eloquent\Builder;
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Database\Eloquent\Scope;

    class StatusScope implements Scope{
    public function apply(Builder $builder, Model $model){
    $builder->where(‘status’, 1);
    }
    }
    e. 此时,还不能实现全局,因为需要在模型设置开关,让其富有灵活性:
    //启用全局作用域,如果发现路径报错,那就在模型代码开头添加:use App\Scopes\StatusScope;
    protected static function booted(){
    parent::booted();
    static::addGlobalScope(new StatusScope());
    }
    Ps: 而在控制器端,并不需要做任何设置,即可自动添加status=1的条件
    f. 当然,如果这个全局只是针对某个模块,并不需要创建一个全局类,直接闭包即可:
    //这里如果不在模型中添加:use Illuminate\Database\Eloquent\Builder;这段也有可能会报错,报错点在下面的第一行
    static::addGlobalScope(‘status’, function(Builder $builder){
    $builder->where(‘status’,0);
    });
    Ps: 注意Builder引入的文件和全局类引入的文件一致,如果引入别的同名类会报错;
    g. 如果某个查询,并不需要这个全局条件,可以单独移出掉:
    //取消名称为status的全局
    $users = User::withoutGlobalScope(‘status’)->get();
    //取消全局类的条件,这个老壁灯如果使用不了的话那就是没用引入类use App\Scopes\StatusScope;
    $users = User::withoutGlobalScope(StatusScope::class)->get();

    PS:还有withoutGlobalScopes([])方法,传递参数取消多个全局