Laravel从刀片指令

时间:2017-11-01 22:20:43

标签: php mysql laravel performance

我从使用Blade指令获得重复查询。我正在检查用户的角色,然后在表格中显示数据,因此查询会反复重复,从而减慢应用程序的速度。

我已经注册了一个刀片服务提供商,在启动方法中我有以下内容:

Blade::if('admin', function () {
    return auth()->check() && auth()->user()->isAdmin();
});

在我的用户模型中:

public function isAdmin()
{
    return $this->hasRole('admin');
}

在我看来:

@admin
    ...
@endadmin

我已经看过缓存查询,但我没有看到为特定用户执行此操作的方法,这是我在这种情况下所需要的。这个问题有标准解决方案吗?

3 个答案:

答案 0 :(得分:1)

我建议您使用类似AccessService的类的实例,该类充满了is_adminuser_role等常见属性。将其填入http中间件然后使用。当然,最好通过缓存扩展它。

<?php

namespace App\Services;

use App\User;

class AccessService{

    private $user;

    private $isAdmin;


    /**
     * @param User $user
     */
    public function setUser(User $user) {
        $this->user = $user;
        $this->isAdmin = $user->isAdmin();
    }


    /**
     * @return boolean
     */
    public function isAdmin(){
        return $this->isAdmin;
    }

}

该服务充满了中间件app\Http\Middleware\Access.php

<?php

namespace App\Http\Middleware;

use App\Services\AccessService;
use Closure;
use Auth;

class Access {

    public function handle($request, Closure $next)
    {
        $accessService = resolve(AccessService::class);

        # current user
        $user = Auth::user();

        if($user) {
            $accessService->setUser($user);
        }

        return $next($request);
    }
}

...已在app\Http\Middleware\Kernel.php

中注册
'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        \App\Http\Middleware\Access::class, // here, right after StartSession
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

所以你只需使用AccessService扩展你的刀片:

use App\Services\AccessService;
...
Blade::if('admin', function () {
    return resolve(AccessService::class)->isAdmin();
});

或者您可以将服务注入到刀片模板@inject('accessService', 'App\Services\AccessService')并像@if($accessService->isAdmin())一样使用

不要忘记在AppServiceProvider.php中将服务注册为单身人士。

答案 1 :(得分:0)

我建议将其角色存储在缓存中,如user:role:{user_id}

如果您正在寻找比默认使用的文件系统更高效的缓存解决方案,您可以使用Redis。

如果您订阅了Laracasts,那么Redis上有一个很棒的课程:https://laracasts.com/series/learn-laravel-and-redis-through-examples

否则,请查看Redis website。 Laravel轻松支持Redis,使用起来轻而易举。

答案 2 :(得分:0)

在我的Laravel应用程序中,我总是创建一个基本控制器,从中扩展我的其他控制器。

我在此基本控制器中做的一件事是将当前经过身份验证的用户存储在实例变量中,并使用所有视图全局共享该用户。以下代码可能不是100%正确,因为我是从内存中写的。但它应该给你一般的想法。

git filter-branch

然后在您的视图和/或Blade指令中,您只需访问共享视图值。