首页 > 解决方案 > Laravel:模型(GlobalScope)上的 boot() 方法中的 request->user()

问题描述

我有一些我无法解释的行为。我正在进行一个相当大的重构,我遇到了一个在代码中已经存在很长时间的问题,但它似乎在重构之前就起作用了。

在某些模型static::addGlobalScope上,用于在需要时扩展某些查询。在此回调方法中,执行请求的用户使用request()->user(). 这可以在回调内部正常工作,但是当移到回调外部时,它会返回null.

工作示例:

protected static function boot()
{
    parent::boot();
    static::addGlobalScope('auth', function (Builder $builder) {
        $user = request()->user();

        if ($user) {
            if ($user->role == 'consultant') {
                $builder->where('user_id', $user->id);
            } elseif ($user->role == 'approver') {
                $builder->whereHas('contract', function ($query) use ($user) {
                    return $query->whereHas('approvers', function ($query) use ($user) {
                        return $query->where('user_id', $user->id);
                    });
                });
            }
        }
    });
}

$user为空的示例。

protected static function boot()
{
    parent::boot();
    $user = request()->user(); // Moved $user outside of the callback

    static::addGlobalScope('auth', function (Builder $builder) use ($user) {
        if ($user) {
            if ($user->role == 'consultant') {
                $builder->where('user_id', $user->id);
            } elseif ($user->role == 'approver') {
                $builder->whereHas('contract', function ($query) use ($user) {
                    return $query->whereHas('approvers', function ($query) use ($user) {
                        return $query->where('user_id', $user->id);
                    });
                });
            }
        }
    });
}

第二个示例取自重构之前的模型。这种方法正在多个模型上使用,这从来没有出现任何问题。有谁知道为什么在方法的回调之外调用$user时为 null ?最重要的是,为什么它以前从未给出过问题?request()->user()boot

标签: phplaraveleloquent

解决方案


这可能与这样一个事实有关:为了在您使用 request()->user() 时获取用户,它必须注册所有全局范围,然后执行查询。它实际上检查会话是否存在,然后查询以使该用户返回用户对象。也许您需要使用本地范围,或者 Auth::check() 可能会完成这项工作。


推荐阅读