You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

128 lines
3.6 KiB

  1. <?php
  2. /**
  3. * Класс кеша.
  4. * Отвечает за кеширование результатов выполнения действий.
  5. *
  6. * @copyright
  7. * @link
  8. * @package Majestic
  9. * @subpackage Cache
  10. * @since
  11. * @version SVN: $Id$
  12. * @filesource $URL$
  13. */
  14. final class Cache
  15. {
  16. private $cache_file;
  17. private $cache_folder;
  18. private $cache_time;
  19. private $mode = 0777;
  20. private $infofile = '_infofile';
  21. const HASH_ENABLE = true;
  22. function __construct($cache_name, $cache_time)
  23. {
  24. if (!preg_match('/[a-zA-Z0-9_]/', $cache_name)) {
  25. throw new MJException('Wrong cache identifier "'.$cache_name.'". Must use only [a-zA-Z0-9_]');
  26. }
  27. if ($cache_name == $this->infofile) {
  28. throw new MJException('Name "'.$this->infofile.'" is reserved. Try another one.');
  29. }
  30. if ($cache_time == 0) {
  31. throw new MJException('cache_time must be non-zero');
  32. }
  33. if ($cache_time > 86400) {
  34. throw new MJException('cache_time cannot be greater than 86400 sec (24 hours)');
  35. }
  36. if (substr($cache_name, 0, 1) == '_') {
  37. $this->cache_folder = CACHE_PATH;
  38. } else {
  39. $parts = explode('_', $cache_name, 2);
  40. $this->cache_folder = CACHE_PATH.'/'.(isset($parts[1]) ? $parts[0] : '_all');
  41. if (self::HASH_ENABLE) {
  42. $hash = md5($cache_name);
  43. $this->cache_folder .= '/'.substr($hash, 0, 1).'/'.substr($hash, 0, 2);
  44. }
  45. }
  46. $this->cache_file = $this->cache_folder.'/'.$cache_name;
  47. if (!is_writable($this->cache_folder)) {
  48. mkdir($this->cache_folder, $this->mode, true);
  49. }
  50. $this->cache_time = (int) $cache_time;
  51. }
  52. /**
  53. * Сохраняет кэш в файл
  54. *
  55. * @param string/array $data - строка (либо одномерный массив) сохраняемых данных
  56. * @return boolean - сохранил или нет
  57. */
  58. function save($data)
  59. {
  60. if ($this->cache_time != 0 && is_writable($this->cache_folder)) {
  61. $this->clearOld(); //очистка старых файлов.
  62. return (bool) file_put_contents($this->cache_file, $data);
  63. }
  64. return false;
  65. }
  66. /**
  67. * Достает кэш из файла
  68. *
  69. * @return string - содержимое кеша
  70. */
  71. function load()
  72. {
  73. if ($this->cache_time != 0) {
  74. return file_get_contents($this->cache_file);
  75. }
  76. return false;
  77. }
  78. /**
  79. * Принудительно очистить кеш
  80. *
  81. */
  82. function reset()
  83. {
  84. @unlink($this->cache_file);
  85. }
  86. /**
  87. * Проверяет, закешированы ли данные с таким именем
  88. *
  89. * @return boolean - закеширован или нет
  90. */
  91. function isCached()
  92. {
  93. if (is_readable($this->cache_file)) {
  94. if ($this->cache_time < 0 || $this->cache_time + filemtime($this->cache_file) > time()) {
  95. return true;
  96. }
  97. $this->reset(); //удалим просроченый файл
  98. }
  99. return false;
  100. }
  101. /**
  102. * Удаление файлов старше суток
  103. *
  104. */
  105. function clearOld()
  106. {
  107. $file = CACHE_PATH.'/'.$this->infofile;
  108. if (!file_exists($file) || date('Ymd', filemtime($file)) != date('Ymd')) {
  109. exec('find '.CACHE_PATH.'/ -mtime +1 -delete'); //не удаляет папки сохраняя структуру
  110. touch($file);
  111. }
  112. }
  113. }
  114. ?>