PageCache.php 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. <?php
  2. /**
  3. * @link http://www.yiiframework.com/
  4. * @copyright Copyright (c) 2008 Yii Software LLC
  5. * @license http://www.yiiframework.com/license/
  6. */
  7. namespace yii\web;
  8. use Yii;
  9. use yii\base\ActionFilter;
  10. use yii\base\Action;
  11. use yii\caching\Dependency;
  12. /**
  13. * The PageCache provides functionality for whole page caching
  14. *
  15. * It is an action filter that can be added to a controller and handles the `beforeAction` event.
  16. *
  17. * To use PageCache, declare it in the `behaviors()` method of your controller class.
  18. * In the following example the filter will be applied to the `list`-action and
  19. * cache the whole page for maximum 60 seconds or until the count of entries in the post table changes.
  20. * It also stores different versions of the page depended on the route ([[varyByRoute]] is true by default),
  21. * the application language and user id.
  22. *
  23. * ~~~
  24. * public function behaviors()
  25. * {
  26. * return [
  27. * 'pageCache' => [
  28. * 'class' => \yii\web\PageCache::className(),
  29. * 'only' => ['list'],
  30. * 'duration' => 60,
  31. * 'dependecy' => [
  32. * 'class' => 'yii\caching\DbDependency',
  33. * 'sql' => 'SELECT COUNT(*) FROM post',
  34. * ],
  35. * 'variations' => [
  36. * Yii::$app->language,
  37. * Yii::$app->user->id
  38. * ]
  39. * ],
  40. * ];
  41. * }
  42. * ~~~
  43. *
  44. * @author Qiang Xue <[email protected]>
  45. * @since 2.0
  46. */
  47. class PageCache extends ActionFilter
  48. {
  49. /**
  50. * @var boolean whether the content being cached should be differentiated according to the route.
  51. * A route consists of the requested controller ID and action ID. Defaults to true.
  52. */
  53. public $varyByRoute = true;
  54. /**
  55. * @var string the application component ID of the [[\yii\caching\Cache|cache]] object.
  56. */
  57. public $cache = 'cache';
  58. /**
  59. * @var integer number of seconds that the data can remain valid in cache.
  60. * Use 0 to indicate that the cached data will never expire.
  61. */
  62. public $duration = 60;
  63. /**
  64. * @var array|Dependency the dependency that the cached content depends on.
  65. * This can be either a [[Dependency]] object or a configuration array for creating the dependency object.
  66. * For example,
  67. *
  68. * ~~~
  69. * [
  70. * 'class' => 'yii\caching\DbDependency',
  71. * 'sql' => 'SELECT MAX(lastModified) FROM Post',
  72. * ]
  73. * ~~~
  74. *
  75. * would make the output cache depends on the last modified time of all posts.
  76. * If any post has its modification time changed, the cached content would be invalidated.
  77. */
  78. public $dependency;
  79. /**
  80. * @var array list of factors that would cause the variation of the content being cached.
  81. * Each factor is a string representing a variation (e.g. the language, a GET parameter).
  82. * The following variation setting will cause the content to be cached in different versions
  83. * according to the current application language:
  84. *
  85. * ~~~
  86. * [
  87. * Yii::$app->language,
  88. * ]
  89. * ~~~
  90. */
  91. public $variations;
  92. /**
  93. * @var boolean whether to enable the fragment cache. You may use this property to turn on and off
  94. * the fragment cache according to specific setting (e.g. enable fragment cache only for GET requests).
  95. */
  96. public $enabled = true;
  97. /**
  98. * @var \yii\base\View the view component to use for caching. If not set, the default application view component
  99. * [[Application::view]] will be used.
  100. */
  101. public $view;
  102. public function init()
  103. {
  104. parent::init();
  105. if ($this->view === null) {
  106. $this->view = Yii::$app->getView();
  107. }
  108. }
  109. /**
  110. * This method is invoked right before an action is to be executed (after all possible filters.)
  111. * You may override this method to do last-minute preparation for the action.
  112. * @param Action $action the action to be executed.
  113. * @return boolean whether the action should continue to be executed.
  114. */
  115. public function beforeAction($action)
  116. {
  117. $properties = [];
  118. foreach (['cache', 'duration', 'dependency', 'variations', 'enabled'] as $name) {
  119. $properties[$name] = $this->$name;
  120. }
  121. $id = $this->varyByRoute ? $action->getUniqueId() : __CLASS__;
  122. ob_start();
  123. ob_implicit_flush(false);
  124. if ($this->view->beginCache($id, $properties)) {
  125. return true;
  126. } else {
  127. Yii::$app->getResponse()->content = ob_get_clean();
  128. return false;
  129. }
  130. }
  131. /**
  132. * This method is invoked right after an action is executed.
  133. * You may override this method to do some postprocessing for the action.
  134. * @param Action $action the action just executed.
  135. * @param mixed $result the action execution result
  136. */
  137. public function afterAction($action, &$result)
  138. {
  139. echo $result;
  140. $this->view->endCache();
  141. $result = ob_get_clean();
  142. }
  143. }