起初使用页面缓存,发现使用于含有参数的方法存在弊端,只能缓存第一次的页面,导致后面所有不同参数的页面均显示第一次缓存页面;没有生成一个参数页面一个缓存;于是,进行了重写页面缓存。

  1. <?php
  2. namespace common\lib;
  3. use Yii;
  4. use yii\caching\Cache;
  5. use yii\di\Instance;
  6. use yii\web\Response;
  7. use yii\filters\PageCache as PCache;
  8. /**
  9. * 重写页面缓存,增加varByParam参数一列
  10. */
  11. class PageCache extends PCache
  12. {
  13. /**
  14. * 参数设置,默认无参数
  15. * 用法:'varByParam' => Yii::$app->request->get('id')
  16. * @var string
  17. */
  18. public $varByParam = '';
  19. public function beforeAction($action)
  20. {
  21. if (!$this->enabled) {
  22. return true;
  23. }
  24. $this->cache = Instance::ensure($this->cache, Cache::className());
  25. if (is_array($this->dependency)) {
  26. $this->dependency = Yii::createObject($this->dependency);
  27. }
  28. $properties = [];
  29. foreach (['cache', 'duration', 'dependency', 'variations'] as $name) {
  30. $properties[$name] = $this->$name;
  31. }
  32. $id = $this->varyByRoute ? $action->getUniqueId().$this->varByParam : __CLASS__;
  33. $response = Yii::$app->getResponse();
  34. ob_start();
  35. ob_implicit_flush(false);
  36. if ($this->view->beginCache($id, $properties)) {
  37. $response->on(Response::EVENT_AFTER_SEND, [$this, 'cacheResponse']);
  38. return true;
  39. } else {
  40. $data = $this->cache->get($this->calculateCacheKey());
  41. if (is_array($data)) {
  42. $this->restoreResponse($response, $data);
  43. }
  44. $response->content = ob_get_clean();
  45. return false;
  46. }
  47. }
  48. }

使用:

  1. [
  2. 'class' => 'common\lib\PageCache',
  3. 'only' => ['view'],
  4. 'duration' => 0, //永不过期
  5. 'varByParam' => Yii::$app->request->get('id'),
  6. ],

liangyunwuxu 评论于 2017-05-21 13:39 举报
受到楼主的启发,去看了源文件,发现能否缓存带参数页面的关键在于生成缓存key是否唯一。

我找到的方法如下,编辑文件yii\filters\PageCache.php文件,找到calculateCacheKey()函数。
编辑$key[]值

  1. $key[] = Yii::$app->requestedRoute;

  1. // 可以支持view等带参数页面的缓存。
  2. $key[] = \Yii::$app->requestedRoute.'/'.implode('/',\Yii::$app->controller->actionParams);

即可对任何带参数的页面进行页面缓存。

当然,自己写个类,覆盖原来的calculateCacheKey()函数也是可以的。
参考:http://www.yiichina.com/tutorial/926

分类: web

标签:   yii2   缓存