Laravel缓存经过身份验证的用户的关系

时间:2016-07-07 15:20:13

标签: php laravel authentication caching laravel-5

在我的应用程序中,我使用Laravel的身份验证系统,并使用依赖注入(或Facade)来访问登录用户。我倾向于通过我的基本控制器访问登录用户,以便我可以在我的子类中轻松访问它:

class Controller extends BaseController
{
    protected $user;

    public function __construct()
    {
        $this->user = \Auth::user();
    }
}

我的用户有很多不同的关系,我倾向于像这样急切地加载:

$this->user->load(['relationshipOne', 'relationshipTwo']);

正如在这个项目中,我希望能够获得持续高流量的流量,我希望尽可能顺利,高效地运行应用程序,以便实现一些缓存。

理想情况下,我需要能够避免重复查询数据库,特别是对于用户的相关记录。因此,在加载关系之后,我需要研究缓存用户对象。

我有想法做这样的事情:

public function __construct()
{
    $userId = \Auth::id();
    if (!is_null($userId)) {
        $this->user = \Cache::remember("user-{$userId}", 60, function() use($userId) {
            return User::with(['relationshipOne', 'relationshipTwo'])->find($userId);
        });
    }
}

但是,我不确定依赖\Auth::id()是否返回非空值来传递身份验证是否安全。有没有人遇到过类似的问题?

2 个答案:

答案 0 :(得分:0)

我建议您使用类似下面的包。 https://github.com/spatie/laravel-responsecache

它缓存响应,您不仅可以将其用于用户对象。

答案 1 :(得分:0)

好吧,经过一番捣乱,我为自己找到了一种解决方案,我想我会分享。

我以为我会放弃缓存实际的User对象,只是让身份验证正常进行,只关注尝试缓存用户的关系。这感觉就像是一种肮脏的方式,因为我的逻辑在模型中:

class User extends Model
{
    // ..

    /**
     * This is the relationship I want to cache
     */
    public function related()
    {
        return $this->hasMany(Related::class);
    }

    /**
     * This method can be used when we want to utilise a cache
     */
    public function getRelated()
    {
        return \Cache::remember("relatedByUser({$this->id})", 60, function() {
            return $this->related;
        });
    }

    /**
     * Do something with the cached relationship
     */
    public function totalRelated()
    {
        return $this->getRelated()->count();
    }
}

在我的情况下,我需要能够在User模型中缓存相关项,因为我在用户中有一些方法可以使用该关系。就像上面totalRelated方法的非常简单的例子一样(我的项目有点复杂)。

当然,如果我在User模型上没有这样的内部方法,那么从我的模型外部调用关系和缓存一样容易(例如在控制器中) )

 class MyController extends Controller
 {
      public function index()
      {
           $related = \Cache::remember("relatedByUser({$this->user->id})", 60, function() {
                return $this->user->related;
           });

           // Do something with the $related items...
      }
 }

同样,这对我来说并不是最好的解决方案,我愿意尝试其他建议。

干杯

编辑:我更进一步,在我的父Model课程上实施了几个方法,以帮助缓存关系并为我的所有关系实施getter方法接受$useCache参数,以使事情更灵活:

父模型类:

class Model extends BaseModel
{
    /**
     * Helper method to get a value from the cache if it exists, or using the provided closure, caching the result for
     * the default cache time.
     *
     * @param $key
     * @param Closure|null $callback
     * @return mixed
     */
    protected function cacheRemember($key, Closure $callback = null)
    {
        return Cache::remember($key, Cache::getDefaultCacheTime(), $callback);
    }

    /**
     * Another helper method to either run a closure to get a value, or if useCache is true, attempt to get the value
     * from the cache, using the provided key and the closure as a means of getting the value if it doesn't exist.
     *
     * @param $useCache
     * @param $key
     * @param Closure $callback
     * @return mixed
     */
    protected function getOrCacheRemember($useCache, $key, Closure $callback)
    {
        return !$useCache ? $callback() : $this->cacheRemember($key, $callback);
    }
}

我的用户类:

class User extends Model
{
    public function related()
    {
        return $this->hasMany(Related::class);
    }

    public function getRelated($useCache = false)
    {
        return $this->getOrCacheRemember($useCache, "relatedByUser({$this->id})", function() {
            return $this->related;
        });
    }
}

用法:

$related = $user->getRelated(); // Gets related from the database
$relatedTwo = $user->getRelated(true); // Gets related from the cache if present (Or from database and caches result)