PageRenderTime 50ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/phpcache.class.php

https://github.com/kolobus/PHPCache
PHP | 247 lines | 178 code | 40 blank | 29 comment | 26 complexity | 3962fe0d6bfda96cc3720145420a9206 MD5 | raw file
  1. <?php
  2. /**
  3. * This program is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this program; if not, write to the Free Software
  15. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. *
  17. * D O N O T R E M O V E T H E S E C O M M E N T S
  18. *
  19. * @Package PHPCache
  20. * @Author Hamid Alipour, http://blog.code-head.com/ http://www.hamidof.com/
  21. */
  22. if( !defined('PHPCACHE_BASE_DIR') ) define('PHPCACHE_BASE_DIR', dirname(__FILE__));
  23. if( !defined('PHPCACHE_DRIVER_DIR') ) define('PHPCACHE_DRIVER_DIR', PHPCACHE_BASE_DIR .DIRECTORY_SEPARATOR .'drivers');
  24. if( !defined('PHPCACHE_BD_LOGIN_ATTEMPT') ) define('PHPCACHE_BD_LOGIN_ATTEMPT', 100);
  25. define('PHPCACHE_TIME_NOW', time());
  26. define('PHPCACHE_1_SECOND', 1);
  27. define('PHPCACHE_1_MINUTE', PHPCACHE_1_SECOND * 60);
  28. define('PHPCACHE_1_HOUR', PHPCACHE_1_MINUTE * 60);
  29. define('PHPCACHE_1_DAY', PHPCACHE_1_HOUR * 24);
  30. define('PHPCACHE_1_WEEK', PHPCACHE_1_DAY * 4);
  31. define('PHPCACHE_1_MONTH', PHPCACHE_1_DAY * 30);
  32. define('PHPCACHE_1_YEAR', PHPCACHE_1_MONTH * 12);
  33. /**
  34. * PHPCACHE_GC_PROBABILITY = 10 &
  35. * PHPCACHE_GC_DIVISOR = 100
  36. * Means there is 10% chance that the garbage collection will be done on each
  37. * PHPCache::configure($database) call
  38. */
  39. if( !defined('PHPCACHE_GC_PROBABILITY') ) define('PHPCACHE_GC_PROBABILITY', 1);
  40. if( !defined('PHPCACHE_GC_DIVISOR') ) define('PHPCACHE_GC_DIVISOR', 100);
  41. /**
  42. * TO = Table optimizer
  43. */
  44. if( !defined('PHPCACHE_TO_PROBABILITY') ) define('PHPCACHE_TO_PROBABILITY', 10);
  45. if( !defined('PHPCACHE_TO_DIVISOR') ) define('PHPCACHE_TO_DIVISOR', 100);
  46. require_once PHPCACHE_BASE_DIR .DIRECTORY_SEPARATOR .'phpcache.interface.php';
  47. require_once PHPCACHE_DRIVER_DIR .DIRECTORY_SEPARATOR .'phpcache.driver.interface.php';
  48. class PHPCache implements PHPCache_Interface {
  49. private $db_handle;
  50. private $db_table;
  51. static private $instance;
  52. private $time_now;
  53. private $last_error;
  54. private function __construct($params) {
  55. if( !isset($params['type']) ) {
  56. $this->trigger_error('I couldn\'t find the database type in $params[\'type\'].');
  57. }
  58. $database_type = strtolower($params['type']);
  59. $driver_file = PHPCACHE_DRIVER_DIR .DIRECTORY_SEPARATOR .'phpcache.driver.' .$database_type .'.class.php';
  60. if( !file_exists($driver_file) ) {
  61. $this->trigger_error('PHPCache doesn\'t support the database type in $params[\'type\'] yet.');
  62. }
  63. require_once($driver_file);
  64. $driver_class = 'PHPCache_Driver_' .$database_type;
  65. $this->db_handle = new $driver_class($params);
  66. $this->db_table = isset($params['table']) ? $params['table'] : 'PHPCache';
  67. $this->time_now = PHPCACHE_TIME_NOW;
  68. $this->last_error = NULL;
  69. $this->clean_up();
  70. }
  71. public static function configure($params) {
  72. if( self::$instance == NULL ) {
  73. self::$instance = new PHPCache($params);
  74. }
  75. }
  76. public static function instance() {
  77. if( self::$instance == NULL ) {
  78. $this->trigger_error('You have to call PHPCache::configure first.');
  79. }
  80. return self::$instance;
  81. }
  82. public function create_table() {
  83. $this->db_handle->create_table($this->db_table);
  84. }
  85. public function store($key, $value, $expires) {
  86. $data = array(
  87. 'PHPCache_key' => $this->db_handle->escape(md5($key)),
  88. 'PHPCache_value' => $this->db_handle->escape(serialize($value)),
  89. 'PHPCache_expires' => $this->db_handle->escape($this->time_now + $expires)
  90. );
  91. $query = "
  92. REPLACE INTO
  93. {$this->db_table}
  94. (
  95. PHPCache_key,
  96. PHPCache_value,
  97. PHPCache_expires
  98. )
  99. VALUES
  100. (
  101. {$data['PHPCache_key']},
  102. {$data['PHPCache_value']},
  103. {$data['PHPCache_expires']}
  104. )
  105. ";
  106. if( $this->db_handle->query($query) ) {
  107. return true;
  108. } else {
  109. $this->last_error = $this->db_handle->error();
  110. return false;
  111. }
  112. }
  113. public function get($key) {
  114. $key = $this->db_handle->escape(md5($key));
  115. $query = "
  116. SELECT
  117. PHPCache_value, PHPCache_expires
  118. FROM
  119. {$this->db_table}
  120. WHERE
  121. PHPCache_key = $key
  122. ";
  123. if( !($result = $this->db_handle->query($query)) ) {
  124. $this->trigger_error($this->db_handle->error());
  125. return false;
  126. }
  127. if( $result->num_rows < 1 ) {
  128. return false;
  129. }
  130. $data = $result->fetch_assoc();
  131. if( $data['PHPCache_expires'] < $this->time_now ) {
  132. return false;
  133. }
  134. if( $data['PHPCache_value'] && trim($data['PHPCache_value']) != '' ) {
  135. $_data = unserialize($data['PHPCache_value']);
  136. if( $_data === false ) {
  137. $this->trigger_error("Unserialize failed, you might need to increase the size of database column {$this->db_table}.PHPCache_value");
  138. return false;
  139. }
  140. return $_data;
  141. } else {
  142. return NULL;
  143. }
  144. }
  145. public function set_expire($key) {
  146. $key = $this->db_handle->escape(md5($key));
  147. $expires = $this->db_handle->escape($this->time_now - PHPCACHE_1_YEAR);
  148. $query = "
  149. REPLACE INTO
  150. {$this->db_table}
  151. (
  152. PHPCache_key,
  153. PHPCache_expires
  154. )
  155. VALUES
  156. (
  157. {$key},
  158. {$expires}
  159. )
  160. ";
  161. $this->db_handle->query($query);
  162. }
  163. public function remove($key) {
  164. $key = $this->db_handle->escape(md5($key));
  165. $query = "
  166. DELETE
  167. FROM
  168. {$this->db_table}
  169. WHERE
  170. PHPCache_key = $key
  171. ";
  172. $this->db_handle->query($query);
  173. }
  174. public function clean_up() {
  175. if( rand(1, PHPCACHE_GC_DIVISOR) <= PHPCACHE_GC_PROBABILITY ) {
  176. $this->gc();
  177. }
  178. if( rand(1, PHPCACHE_TO_DIVISOR) <= PHPCACHE_TO_PROBABILITY ) {
  179. $this->optimize_table();
  180. }
  181. }
  182. public function gc() {
  183. $query = "
  184. DELETE
  185. FROM
  186. {$this->db_table}
  187. WHERE
  188. PHPCache_expires < {$this->time_now}
  189. ";
  190. $this->db_handle->query($query);
  191. }
  192. public function optimize_table() {
  193. $this->db_handle->optimize_table($this->db_table);
  194. }
  195. private function trigger_error($msg) {
  196. $this->last_error = $msg;
  197. trigger_error("PHPCache Error: $msg", E_USER_ERROR);
  198. exit;
  199. }
  200. public function has_error() {
  201. return $this->last_error != NULL;
  202. }
  203. public function last_error() {
  204. return $this->last_error;
  205. }
  206. } // Class
  207. ?>