PhpArrayCache.php 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\Cache\Simple;
  11. use Psr\SimpleCache\CacheInterface as Psr16CacheInterface;
  12. use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
  13. use Symfony\Component\Cache\Exception\InvalidArgumentException;
  14. use Symfony\Component\Cache\PruneableInterface;
  15. use Symfony\Component\Cache\ResettableInterface;
  16. use Symfony\Component\Cache\Traits\PhpArrayTrait;
  17. use Symfony\Contracts\Cache\CacheInterface;
  18. @trigger_error(sprintf('The "%s" class is deprecated since Symfony 4.3, use "%s" and type-hint for "%s" instead.', PhpArrayCache::class, PhpArrayAdapter::class, CacheInterface::class), \E_USER_DEPRECATED);
  19. /**
  20. * @deprecated since Symfony 4.3, use PhpArrayAdapter and type-hint for CacheInterface instead.
  21. */
  22. class PhpArrayCache implements Psr16CacheInterface, PruneableInterface, ResettableInterface
  23. {
  24. use PhpArrayTrait;
  25. /**
  26. * @param string $file The PHP file were values are cached
  27. * @param Psr16CacheInterface $fallbackPool A pool to fallback on when an item is not hit
  28. */
  29. public function __construct(string $file, Psr16CacheInterface $fallbackPool)
  30. {
  31. $this->file = $file;
  32. $this->pool = $fallbackPool;
  33. }
  34. /**
  35. * This adapter takes advantage of how PHP stores arrays in its latest versions.
  36. *
  37. * @param string $file The PHP file were values are cached
  38. * @param CacheInterface $fallbackPool A pool to fallback on when an item is not hit
  39. *
  40. * @return Psr16CacheInterface
  41. */
  42. public static function create($file, Psr16CacheInterface $fallbackPool)
  43. {
  44. return new static($file, $fallbackPool);
  45. }
  46. /**
  47. * {@inheritdoc}
  48. */
  49. public function get($key, $default = null)
  50. {
  51. if (!\is_string($key)) {
  52. throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
  53. }
  54. if (null === $this->values) {
  55. $this->initialize();
  56. }
  57. if (!isset($this->keys[$key])) {
  58. return $this->pool->get($key, $default);
  59. }
  60. $value = $this->values[$this->keys[$key]];
  61. if ('N;' === $value) {
  62. return null;
  63. }
  64. if ($value instanceof \Closure) {
  65. try {
  66. return $value();
  67. } catch (\Throwable $e) {
  68. return $default;
  69. }
  70. }
  71. return $value;
  72. }
  73. /**
  74. * {@inheritdoc}
  75. *
  76. * @return iterable
  77. */
  78. public function getMultiple($keys, $default = null)
  79. {
  80. if ($keys instanceof \Traversable) {
  81. $keys = iterator_to_array($keys, false);
  82. } elseif (!\is_array($keys)) {
  83. throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
  84. }
  85. foreach ($keys as $key) {
  86. if (!\is_string($key)) {
  87. throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
  88. }
  89. }
  90. if (null === $this->values) {
  91. $this->initialize();
  92. }
  93. return $this->generateItems($keys, $default);
  94. }
  95. /**
  96. * {@inheritdoc}
  97. *
  98. * @return bool
  99. */
  100. public function has($key)
  101. {
  102. if (!\is_string($key)) {
  103. throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
  104. }
  105. if (null === $this->values) {
  106. $this->initialize();
  107. }
  108. return isset($this->keys[$key]) || $this->pool->has($key);
  109. }
  110. /**
  111. * {@inheritdoc}
  112. *
  113. * @return bool
  114. */
  115. public function delete($key)
  116. {
  117. if (!\is_string($key)) {
  118. throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
  119. }
  120. if (null === $this->values) {
  121. $this->initialize();
  122. }
  123. return !isset($this->keys[$key]) && $this->pool->delete($key);
  124. }
  125. /**
  126. * {@inheritdoc}
  127. *
  128. * @return bool
  129. */
  130. public function deleteMultiple($keys)
  131. {
  132. if (!\is_array($keys) && !$keys instanceof \Traversable) {
  133. throw new InvalidArgumentException(sprintf('Cache keys must be array or Traversable, "%s" given.', \is_object($keys) ? \get_class($keys) : \gettype($keys)));
  134. }
  135. $deleted = true;
  136. $fallbackKeys = [];
  137. foreach ($keys as $key) {
  138. if (!\is_string($key)) {
  139. throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
  140. }
  141. if (isset($this->keys[$key])) {
  142. $deleted = false;
  143. } else {
  144. $fallbackKeys[] = $key;
  145. }
  146. }
  147. if (null === $this->values) {
  148. $this->initialize();
  149. }
  150. if ($fallbackKeys) {
  151. $deleted = $this->pool->deleteMultiple($fallbackKeys) && $deleted;
  152. }
  153. return $deleted;
  154. }
  155. /**
  156. * {@inheritdoc}
  157. *
  158. * @return bool
  159. */
  160. public function set($key, $value, $ttl = null)
  161. {
  162. if (!\is_string($key)) {
  163. throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
  164. }
  165. if (null === $this->values) {
  166. $this->initialize();
  167. }
  168. return !isset($this->keys[$key]) && $this->pool->set($key, $value, $ttl);
  169. }
  170. /**
  171. * {@inheritdoc}
  172. *
  173. * @return bool
  174. */
  175. public function setMultiple($values, $ttl = null)
  176. {
  177. if (!\is_array($values) && !$values instanceof \Traversable) {
  178. throw new InvalidArgumentException(sprintf('Cache values must be array or Traversable, "%s" given.', \is_object($values) ? \get_class($values) : \gettype($values)));
  179. }
  180. $saved = true;
  181. $fallbackValues = [];
  182. foreach ($values as $key => $value) {
  183. if (!\is_string($key) && !\is_int($key)) {
  184. throw new InvalidArgumentException(sprintf('Cache key must be string, "%s" given.', \is_object($key) ? \get_class($key) : \gettype($key)));
  185. }
  186. if (isset($this->keys[$key])) {
  187. $saved = false;
  188. } else {
  189. $fallbackValues[$key] = $value;
  190. }
  191. }
  192. if ($fallbackValues) {
  193. $saved = $this->pool->setMultiple($fallbackValues, $ttl) && $saved;
  194. }
  195. return $saved;
  196. }
  197. private function generateItems(array $keys, $default): iterable
  198. {
  199. $fallbackKeys = [];
  200. foreach ($keys as $key) {
  201. if (isset($this->keys[$key])) {
  202. $value = $this->values[$this->keys[$key]];
  203. if ('N;' === $value) {
  204. yield $key => null;
  205. } elseif ($value instanceof \Closure) {
  206. try {
  207. yield $key => $value();
  208. } catch (\Throwable $e) {
  209. yield $key => $default;
  210. }
  211. } else {
  212. yield $key => $value;
  213. }
  214. } else {
  215. $fallbackKeys[] = $key;
  216. }
  217. }
  218. if ($fallbackKeys) {
  219. yield from $this->pool->getMultiple($fallbackKeys, $default);
  220. }
  221. }
  222. }