Mat*_*cki 8 php ioc-container inversion-of-control laravel laravel-5.8
仅当经过身份验证的用户的角色等于某些内容时,我才需要应用特定的全局范围。因此,具有特定角色的用户将只能对给定的记录子集执行查询。
我可以轻松处理 User 模型(当前登录的用户),但不能处理范围内的 apply 方法。
https://github.com/laravel/framework/issues/22316#issuecomment-349548374
在 auth 中间件运行之前,范围构造函数很早就执行了。在 apply 方法中解析用户,而不是在构造函数中。
好的,所以我在apply方法中:
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class UserScopeForSalesContactAdmin implements Scope
{
/**
* Apply the scope to a given Eloquent query builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
dd('within apply', auth()->user());
dd(auth()->user()); // won't work
$builder->where('foo', '=', 'something from currently logged in user');
}
}
Run Code Online (Sandbox Code Playgroud)
显然第二个dd给出:
达到“512”的最大函数嵌套级别,中止!
如何解决这个问题?我想我应该通过调用 IOC 容器,app()->make()然后呢?
感谢您的任何提示。
编辑:我想我明白是什么导致了无限循环(https://github.com/laravel/framework/issues/26113)但我仍然需要找到一种获得用户的最佳方法......
您正在寻找的方法正是Auth::hasUser(). 该方法是通过我的 PR 在 Laravel 5.6 中添加的。
[5.6] 添加确定当前用户是否已通过身份验证而不会触发 mpyw 的副作用的能力 · 拉取请求 #24518 · laravel/框架
<?php
namespace App\Scopes;
use Illuminate\Database\Eloquent\Scope;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
class UserScopeForSalesContactAdmin implements Scope
{
/**
* Apply the scope to a given Eloquent query builder.
*
* @param \Illuminate\Database\Eloquent\Builder $builder
* @param \Illuminate\Database\Eloquent\Model $model
* @return void
*/
public function apply(Builder $builder, Model $model)
{
if (Auth::hasUser() && Auth::user()->role === 'something') {
$builder->where('foo', '=', 'something from currently logged in user');
}
}
}
Run Code Online (Sandbox Code Playgroud)
只需致电Auth::hasUser()以防止Auth::user()造成副作用。
这里的问题是您正在为 User 定义一个范围,在使用 Auth::user() 检索用户时,它将在解决第一个方法调用之前再次利用该范围,并且从那里我们有一个 StackOverflow。我认为有一个聪明的方法,覆盖守卫,并将用户模型保存在您可以从那里取出的类上,但我也不喜欢使用内置Laravel功能进行调整。
一个简单的方法可能是利用 Auth::id 并使用 DB::table 获取所需的信息,它不太漂亮,但我认为这是解决问题的直接方法。
public function apply(Builder $builder, Model $model)
{
// this will not trigger the scope when you fetch it out again, and avoiding the stackoverflow
$user = DB::table('users')->where('id', Auth::id())->get()->first();
$builder->where('foo', '=', $user['the_answer_to_life']);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3608 次 |
| 最近记录: |