Cache.php 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. <?php
  2. declare(strict_types=1);
  3. namespace PhpMyAdmin\Query;
  4. use PhpMyAdmin\Util;
  5. use function array_shift;
  6. use function count;
  7. use function is_array;
  8. /**
  9. * Handles caching results
  10. */
  11. class Cache
  12. {
  13. /** @var array[] Table data cache */
  14. private $tableCache = [];
  15. /**
  16. * Caches table data so Table does not require to issue
  17. * SHOW TABLE STATUS again
  18. *
  19. * @param mixed[][] $tables information for tables of some databases
  20. */
  21. public function cacheTableData(string $database, array $tables): void
  22. {
  23. // Note: This function must not use array_merge because numerical indices must be preserved.
  24. // When an entry already exists for the database in cache, we merge the incoming data with existing data.
  25. // The union operator appends elements from right to left unless they exists on the left already.
  26. // Doing the union with incoming data on the left ensures that when we reread table status from DB,
  27. // we overwrite whatever was in cache with the new data.
  28. if (isset($this->tableCache[$database])) {
  29. $this->tableCache[$database] = $tables + $this->tableCache[$database];
  30. } else {
  31. $this->tableCache[$database] = $tables;
  32. }
  33. }
  34. /**
  35. * Set an item in table cache using dot notation.
  36. *
  37. * @param array|null $contentPath Array with the target path
  38. * @param mixed $value Target value
  39. */
  40. public function cacheTableContent(?array $contentPath, $value): void
  41. {
  42. $loc = &$this->tableCache;
  43. if (! isset($contentPath)) {
  44. $loc = $value;
  45. return;
  46. }
  47. while (count($contentPath) > 1) {
  48. $key = array_shift($contentPath);
  49. // If the key doesn't exist at this depth, we will just create an empty
  50. // array to hold the next value, allowing us to create the arrays to hold
  51. // final values at the correct depth. Then we'll keep digging into the
  52. // array.
  53. if (! isset($loc[$key]) || ! is_array($loc[$key])) {
  54. $loc[$key] = [];
  55. }
  56. $loc = &$loc[$key];
  57. }
  58. $loc[array_shift($contentPath)] = $value;
  59. }
  60. /**
  61. * Get a cached value from table cache.
  62. *
  63. * @param array $contentPath Array of the name of the target value
  64. * @param mixed $default Return value on cache miss
  65. *
  66. * @return mixed cached value or default
  67. */
  68. public function getCachedTableContent(array $contentPath, $default = null)
  69. {
  70. return Util::getValueByKey($this->tableCache, $contentPath, $default);
  71. }
  72. public function getCache(): array
  73. {
  74. return $this->tableCache;
  75. }
  76. public function clearTableCache(): void
  77. {
  78. $this->tableCache = [];
  79. }
  80. }