Yii2页面缓存失效

4

有没有可能针对特定操作使页面缓存无效或删除?

考虑以下情况:

class SiteController extends Controller
{
    public function behaviors()
    {
        return [
            'pageCache' => [
                'class' => PageCache::className(),
                'duration' => Yii::$app->params['cacheTime'], // seconds
                'variations' => [
                    Yii::$app->language,
                    Yii::$app->request->get('id'), 
                ],
            ],
        ];
    }

    public function actionIndex( $id )
    {
       // action code 
    }
}

现在我想要移除/使失效缓存:

操作 en/site/index?id=1

目前我正在考虑编写一些代码在控制台应用程序中,但不知道如何实现。

编辑1: 我尝试手动重建/使失效缓存来针对特定的操作。该代码不能依赖于“依赖项”,因为几乎不可能为该操作实现此功能。

编辑2: 任务是仅为特定操作(页面)重建缓存,保留其他缓存不变。


如果我理解正确,您想要禁用特定操作的缓存功能? - Muhammad Omer Aslam
@MuhammadOmerAslam 我想要为特定的操作重新构建缓存。 - sim
4个回答

3
你可以使用 TagDependency 实现更细粒度的失效:
public function behaviors()
{
    return [
        'pageCache' => [
            'class' => PageCache::className(),
            'duration' => Yii::$app->params['cacheTime'], // seconds
            'variations' => [
                Yii::$app->language,
                Yii::$app->request->get('id'), 
            ],
            'dependency' => new \yii\caching\TagDependency([
                'tags' => [
                    Yii::$app->requestedRoute,
                    Yii::$app->request->get('id'),
                ],
            ]),
        ],
    ];
}

清除缓存的方法:

TagDependency::invalidate(Yii::$app->cache, [
    'site/index', // route of action 
    123, // ID of page
]);

1

如果有其他人需要... Yii2没有提供本地函数来使特定页面的缓存失效,但是可以使用缓存组件的删除函数。但是需要知道所请求页面的生成键,而生成该键的函数是受保护的(calculateCacheKey())。因此,最好的方式是创建一个扩展自\yii\filters\PageCache的自定义类。

    'pageCache' => function () {
        return new class extends \yii\filters\PageCache{
            public function init(){
                parent::init();
                $this->except = ['index'];
                $this->duration = Yii::$app->params['cacheTime'], // seconds;
                $this->variations = [
                   Yii::$app->language,
                   Yii::$app->request->get('id'), 
                ];
                if(Yii::$app->request->get('IC') == 1)
                    Yii::$app->cache->delete($this->calculateCacheKey());
            }
            public function beforeCacheResponse(){                  
                return Yii::$app->request->get('IC') != 1;
            }
        };
    },

在提供的代码中,为了简单起见,我使用了一个匿名类(PHP 7)。 但是你可以按照自己的意愿创建你的类,并将其路径作为“class”参数通知,就像在问题显示的配置中所看到的那样。
请注意,我使用了一个简单的逻辑来使缓存失效,检查是否存在GET参数IC == 1,你可以使用任何你想要的逻辑。
如果在使缓存失效后,你不想创建新的缓存,请在beforeCacheResponse中返回false,它来自于\yii\filters\PageCache。

0

我知道这个功能,但是没有可以使用的依赖项。 - sim
你可以设置一个仅用于清除缓存的依赖值,但这有点不正规。如果你能获取到计算出来的键,你应该能够使用数据缓存方法,例如delete()来实现你想要的功能。 - ldg
谢谢,目前我也在考虑这种方式,但我仍然希望有一个简单的解决方案来完成这个任务。在我看来,手动清除某个页面操作的缓存是一项常见任务。 - sim

0

如果我理解正确,您正在尝试仅针对特定操作禁用缓存,并根据DOCS,您可以使用以下选项明确标识应用缓存过滤器的操作ID或不应用缓存过滤器的操作ID。

$except array 此过滤器不应用于的操作ID列表。 yii\base\ActionFilter

$only array 此过滤器应用于的操作ID列表。

以下内容适用于您

return [
        'pageCache' => [
            'class' => PageCache::className(),
            'except'=>['index']
            'duration' => Yii::$app->params['cacheTime'], // seconds
            'variations' => [
                Yii::$app->language,
                Yii::$app->request->get('id'), 
            ],
        ],
    ];

我尝试手动重建/失效特定操作的缓存。该代码无法依赖于“依赖项”,因为对于该操作几乎不可能实现。 - sim
好的,文档上说当您需要使所有缓存数据无效时,可以调用 yii\caching\Cache::flush() 您还可以使用控制台命令 flush 或者 to 来查看已存储的缓存。 @sim - Muhammad Omer Aslam
这个命令将清除所有缓存数据,但如果任务只是为一个操作无效地使缓存失效并重建,则不起作用。 - sim
如果您检查我提供的链接,它会提供控制台命令来列出所有使用的缓存,难道它们对您没有帮助吗?@sim - Muhammad Omer Aslam
不,命令“yii cache”列出的是在配置文件中配置的缓存组件。缓存组件的配置表示整个存储而不是特定的操作或页面。 - sim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接