关于 Laravel 的理论问题在这里。
所以我要做的缓存示例是:
Article::with('comments')->remember(5)->get();
理想情况下,我希望有一个文章更新事件,当该模型的实例(已缓存)的 ID 更新时,我想忘记该键(即使它是被遗忘的查询的整个结果,而不仅仅是那一个模型实例),有可能这样做吗?
如果没有,是否有某种方法可以合理地干净地实现这一点?
所以我一直在寻找与 OP 相同的问题的答案,但对解决方案并不满意。所以我最近开始玩这个并浏览框架的源代码,我发现该remember()
方法接受调用的第二个参数key
,并且由于某种原因它没有记录在他们的网站上(或者我错过了那个?)。
现在的好处是,数据库构建器使用相同的缓存驱动程序,该驱动程序在下面配置,app/config/cache.php
或者我应该说这里记录的相同缓存系统 -缓存。所以如果你将 min 和 key 传递给remember()
,你可以使用相同的 key 来清除缓存 usingCache::forget()
方法,事实上,你几乎可以使用官方网站Cache
上列出的所有方法,比如, ,等。但我不除非您知道自己在做什么,否则建议您使用其他方法。Cache::get()
Cache::add()
Cache::put()
这是一个示例,供您和其他人理解我的意思。
Article::with('comments')->remember(5, 'article_comments')->get();
现在上面的查询结果将被缓存并与article_comments
密钥相关联,然后可以随时使用它来清除它(在我的情况下,我在更新时这样做)。
所以现在如果我想清除该缓存,无论它记住多少时间。我可以通过调用来做到这一点Cache::forget('article_comments');
,它应该可以按预期工作。
希望这对每个人都有帮助:)
我认为一个好方法是这样的:
$value = Cache::remember('users', $minutes, function()
{
return DB::table('users')->get();
});
然后使用Model Observers来检测更新模型的事件
class UserObserver {
public function saving($model)
{
//
}
public function saved($model)
{
// forget from cache
Cache::forget('users');
}
}
User::observe(new UserObserver);
目前没有简单的方法。但是我找到了这个解决方法,到目前为止它对我有用。
首先你必须扩展Illuminate\Database\Query\Builder
.
<?php
class ModifiedBuilder extends Illuminate\Database\Query\Builder {
protected $forgetRequested = false;
public function forget()
{
$this->forgetRequested = true;
}
public function getCached($columns = array('*'))
{
if (is_null($this->columns)) $this->columns = $columns;
list($key, $minutes) = $this->getCacheInfo();
// If the query is requested ot be cached, we will cache it using a unique key
// for this database connection and query statement, including the bindings
// that are used on this query, providing great convenience when caching.
$cache = $this->connection->getCacheManager();
$callback = $this->getCacheCallback($columns);
if($this->forgetRequested) {
$cache->forget($key);
$this->forgetRequested = false;
}
return $cache->remember($key, $minutes, $callback);
}
}
然后你必须创建扩展 Eloquent 模型的新类。
<?php
class BaseModel extends Eloquent {
protected function newBaseQueryBuilder() {
$conn = $this->getConnection();
$grammar = $conn->getQueryGrammar();
return new ModifiedBuilder($conn, $grammar, $conn->getPostProcessor());
}
}
现在在创建 Eloquent 模型时,不要扩展模型,而是Eloquent
扩展新创建的BaseModel
.
现在您可以remember
照常查询结果。
YourModel::remember(10)->get();
当您想丢弃缓存的结果时,您所要做的就是
YourModel::forget()->get();
如果您之前记住了结果,那么在清除缓存的结果后,模型将在这段时间内继续记住结果。
希望这可以帮助。
我正在测试调试模式。所以我发现如果你在构造函数中对 app.debug 进行测试,你就可以清除与键关联的缓存。无需为每个函数复制代码。
class Events {
public function __construct() {
if (\Config::get('app.debug')) {
Cache::forget('events');
}
}
public static function all() {
$events = \DB::table('events as e')
->select('e.*')
->where('enabled', 1)
->remember(30, 'events')
->get();
return $events;
}
}