BxDolCacheFile.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <?php defined('BX_DOL') or die('hack attempt');
  2. /**
  3. * Copyright (c) UNA, Inc - https://una.io
  4. * MIT License - https://opensource.org/licenses/MIT
  5. *
  6. * @defgroup UnaCore UNA Core
  7. * @{
  8. */
  9. class BxDolCacheFile extends BxDolCache
  10. {
  11. protected $sPath;
  12. /**
  13. * constructor
  14. */
  15. function __construct()
  16. {
  17. parent::__construct();
  18. $this->sPath = BX_DIRECTORY_PATH_CACHE;
  19. }
  20. /**
  21. * Get all data from the cache file.
  22. *
  23. * @param string $sKey - file name
  24. * @param int $iTTL - time to live
  25. * @return the data is got from cache.
  26. */
  27. function getData($sKey, $iTTL = false)
  28. {
  29. if (!file_exists($this->sPath . $sKey))
  30. return null;
  31. if ($iTTL > 0 && $this->_removeFileIfTtlExpired ($this->sPath . $sKey, $iTTL))
  32. return null;
  33. include($this->sPath . $sKey);
  34. if (!isset($mixedData))
  35. return null;
  36. return $mixedData;
  37. }
  38. /**
  39. * Save all data in cache file.
  40. *
  41. * @param string $sKey - file name
  42. * @param mixed $mixedData - the data to be cached in the file
  43. * @param int $iTTL - time to live
  44. * @return boolean result of operation.
  45. */
  46. function setData($sKey, $mixedData, $iTTL = false)
  47. {
  48. $sFileName = $this->sPath . $sKey;
  49. $sFileNameTmp = $this->sPath . '.' . uniqid('', true) . '.tmp';
  50. if(file_exists($sFileName) && !is_writable($sFileName))
  51. return false;
  52. $content = '<?php $mixedData=' . var_export($mixedData, true) . '; ?>';
  53. if (false === file_put_contents($sFileNameTmp, $content))
  54. return false;
  55. rename($sFileNameTmp, $sFileName);
  56. @chmod($sFileName, 0666);
  57. if (function_exists('opcache_invalidate')) opcache_invalidate($sFileName, true);
  58. return true;
  59. }
  60. /**
  61. * Delete cache file.
  62. *
  63. * @param string $sKey - file name
  64. * @return result of the operation
  65. */
  66. function delData($sKey)
  67. {
  68. $sFile = $this->sPath . $sKey;
  69. return !file_exists($sFile) || $this->_unlinkFile($sFile);
  70. }
  71. /**
  72. * remove all data from cache by key prefix
  73. * @return true on success
  74. */
  75. function removeAllByPrefix ($s)
  76. {
  77. if (!($rHandler = opendir($this->sPath)))
  78. return false;
  79. $l = strlen($s);
  80. while (($sFile = readdir($rHandler)) !== false)
  81. if (0 === strncmp($sFile, $s, $l))
  82. $this->_unlinkFile($this->sPath . $sFile);
  83. closedir($rHandler);
  84. return true;
  85. }
  86. /**
  87. * get size of cached data by name prefix
  88. */
  89. function getSizeByPrefix ($s)
  90. {
  91. if (!($rHandler = opendir($this->sPath)))
  92. return false;
  93. $iSize = 0;
  94. $l = strlen($s);
  95. while (($sFile = readdir($rHandler)) !== false)
  96. if (0 === strncmp($sFile, $s, $l))
  97. $iSize += @filesize ($this->sPath . $sFile);
  98. closedir($rHandler);
  99. return $iSize;
  100. }
  101. /**
  102. * remove file from dist if TTL expored
  103. * @param string $sFile - full path to filename
  104. * @param int $iTTL - time to live in seconds
  105. * @return true if TTL is expired and file is deleted or false otherwise
  106. */
  107. function _removeFileIfTtlExpired ($sFile, $iTTL)
  108. {
  109. $iTimeDiff = time() - filectime($sFile);
  110. if ($iTimeDiff > $iTTL) {
  111. $this->_unlinkFile($sFile);
  112. return true;
  113. } else {
  114. return false;
  115. }
  116. }
  117. /**
  118. * Remove a cache file together with its opcache entry.
  119. *
  120. * Cache files are PHP scripts read with include(), so opcache keeps a compiled copy of each of them.
  121. * It never evicts entries on its own, and once a file is gone opcache_invalidate() can no longer resolve
  122. * its path, so a file removed with a plain unlink() leaves a dead entry behind for good. With hash-named
  123. * cache files being regenerated all the time such entries pile up until the cache is full and every
  124. * script that no longer fits is recompiled on every request. Invalidating before the unlink turns the
  125. * entry into wasted memory instead, which opcache reclaims with its next restart.
  126. *
  127. * @param string $sFile - full path to the file
  128. * @return true if the file is deleted, false otherwise
  129. */
  130. protected function _unlinkFile ($sFile)
  131. {
  132. if (function_exists('opcache_invalidate'))
  133. opcache_invalidate($sFile, true);
  134. return @unlink($sFile);
  135. }
  136. }
  137. /** @} */