TagDependency.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  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\caching;
  8. /**
  9. * TagDependency associates a cached data item with one or multiple [[tags]].
  10. *
  11. * By calling [[invalidate()]], you can invalidate all cached data items that are associated with the specified tag name(s).
  12. *
  13. * ```php
  14. * // setting multiple cache keys to store data forever and tagging them with "user-123"
  15. * Yii::$app->cache->set('user_42_profile', '', 0, new TagDependency(['tags' => 'user-123']));
  16. * Yii::$app->cache->set('user_42_stats', '', 0, new TagDependency(['tags' => 'user-123']));
  17. *
  18. * // invalidating all keys tagged with "user-123"
  19. * TagDependency::invalidate(Yii::$app->cache, 'user-123');
  20. * ```
  21. *
  22. * For more details and usage information on Cache, see the [guide article on caching](guide:caching-overview).
  23. *
  24. * @author Qiang Xue <qiang.xue@gmail.com>
  25. * @since 2.0
  26. */
  27. class TagDependency extends Dependency
  28. {
  29. /**
  30. * @var string|array a list of tag names for this dependency. For a single tag, you may specify it as a string.
  31. */
  32. public $tags = [];
  33. /**
  34. * Generates the data needed to determine if dependency has been changed.
  35. * This method does nothing in this class.
  36. * @param CacheInterface $cache the cache component that is currently evaluating this dependency
  37. * @return mixed the data needed to determine if dependency has been changed.
  38. */
  39. protected function generateDependencyData($cache)
  40. {
  41. $timestamps = $this->getTimestamps($cache, (array) $this->tags);
  42. $newKeys = [];
  43. foreach ($timestamps as $key => $timestamp) {
  44. if ($timestamp === false) {
  45. $newKeys[] = $key;
  46. }
  47. }
  48. if (!empty($newKeys)) {
  49. $timestamps = array_merge($timestamps, static::touchKeys($cache, $newKeys));
  50. }
  51. return $timestamps;
  52. }
  53. /**
  54. * {@inheritdoc}
  55. */
  56. public function isChanged($cache)
  57. {
  58. $timestamps = $this->getTimestamps($cache, (array) $this->tags);
  59. return $timestamps !== $this->data;
  60. }
  61. /**
  62. * Invalidates all of the cached data items that are associated with any of the specified [[tags]].
  63. * @param CacheInterface $cache the cache component that caches the data items
  64. * @param string|array $tags
  65. */
  66. public static function invalidate($cache, $tags)
  67. {
  68. $keys = [];
  69. foreach ((array) $tags as $tag) {
  70. $keys[] = $cache->buildKey([__CLASS__, $tag]);
  71. }
  72. static::touchKeys($cache, $keys);
  73. }
  74. /**
  75. * Generates the timestamp for the specified cache keys.
  76. * @param CacheInterface $cache
  77. * @param string[] $keys
  78. * @return array the timestamp indexed by cache keys
  79. */
  80. protected static function touchKeys($cache, $keys)
  81. {
  82. $items = [];
  83. $time = microtime();
  84. foreach ($keys as $key) {
  85. $items[$key] = $time;
  86. }
  87. $cache->multiSet($items);
  88. return $items;
  89. }
  90. /**
  91. * Returns the timestamps for the specified tags.
  92. * @param CacheInterface $cache
  93. * @param string[] $tags
  94. * @return array the timestamps indexed by the specified tags.
  95. */
  96. protected function getTimestamps($cache, $tags)
  97. {
  98. if (empty($tags)) {
  99. return [];
  100. }
  101. $keys = [];
  102. foreach ($tags as $tag) {
  103. $keys[] = $cache->buildKey([__CLASS__, $tag]);
  104. }
  105. return $cache->multiGet($keys);
  106. }
  107. }