Posted By

TimoZachi on 09/13/11


Tagged

mysql class session data results caching


Versions (?)

SessCacher: Class for caching data through php session


 / Published in: PHP
 

This is a custom class for caching results through php's session. The class can be used to cache anything, but i use it to cache mysql results so i don't have to get all the time the results by querying MySQL (wich may take a long time, especialy if MySQL's server is not the same as PHP's server), increasing enormously performance. Since the database is in constant actualization, there is an optional parameter to limit the maximun number of times you want to reuse the cached data. The class is well commented with an example on how to use it bellow.

  1. <?php
  2. class SessCacher
  3. {
  4. //constant with self-documented names that holds this class error codes num
  5. const MAX_USES_TOO_LOW = 9000;
  6.  
  7. const INFINITE = -1;
  8.  
  9. /**
  10. * If false (Default), this class will apply md5 php function to compress the cache key.
  11. */
  12. public static $useRawKey = false;
  13.  
  14. private static $_sessKey = 'SessCacher';
  15.  
  16. //Constructor private, no instantiation. Use this class staticaly
  17. private function __construct()
  18. {}
  19.  
  20. /**
  21. * This function is used to cache any data through php's SESSION.
  22. * To reuse the cached data use see function GetCache.
  23. *
  24. * $datakey: A key (any string) to uniquely identify the data you are caching.
  25. * You will need this key to retrieve the cached data later.
  26. *
  27. * $data: The data you want to cache (any data).
  28. *
  29. * $maxCacheUses: This will limit how many times you want to retreive the data.
  30. * The default value is SessCacher::INFINITE times, wich means the cached data will only be
  31. * deleted after the session ends.
  32. *
  33. * $ifNotExists: If you are trying to cache a data that is already cached, the
  34. * data you are trying to chache will not override the previous data if
  35. * $ifNotExists = true (Default value).
  36. */
  37. public static function SetCache($datakey, $data, $maxCacheUses = self::INFINITE, $ifNotExists = true)
  38. {
  39. if($maxCacheUses != self::INFINITE && $maxCacheUses < 1)
  40. {
  41. throw new Exception('param $maxCacheUses: ' . $maxCacheUses .
  42. ' cannot be lower than 1. Use SessCacher::DelCache() to delete cache.',
  43. self::MAX_USES_TOO_LOW);
  44. }
  45. self::CheckKey();
  46.  
  47. $real_key = self::$useRawKey ? $datakey : md5($datakey);
  48. if(!$ifNotExists || !array_key_exists($real_key, $_SESSION[self::$_sessKey]))
  49. {
  50. $_SESSION[self::$_sessKey][$real_key] = array($data, 0, $maxCacheUses);
  51. }
  52. }
  53. /**
  54. * Retrieves a previous cached data using SetCache. If a cache doesn't exists,
  55. * this function retrieves null.
  56. *
  57. * $datakey: A key (any string) that uniquely identifyes the data you cached.
  58. * This has to be the same string that you used on the function SetCache.
  59. */
  60. public static function GetCache($datakey)
  61. {
  62. $return = null;
  63. self::CheckKey();
  64.  
  65. $real_key = self::$useRawKey ? $datakey : md5($datakey);
  66. if(!array_key_exists($real_key, $_SESSION[self::$_sessKey])) return $return;
  67.  
  68. $data = $_SESSION[self::$_sessKey][$real_key];
  69. if($data[2] == self::INFINITE) $return = $data[0];
  70. else
  71. {
  72. $return = $data[0];
  73. $_SESSION[self::$_sessKey][$real_key][1] = $data[1] = $data[1] + 1;
  74. if($data[1] >= $data[2]) unset($_SESSION[self::$_sessKey][$real_key]);
  75. }
  76. return $return;
  77. }
  78. /**
  79. * Deletes a cached data if exists (if it was cached using SetCache).
  80. *
  81. * $datakey: A key (any string) that uniquely identifyes the data you cached.
  82. * This has to be the same string that you used on the function SetCache.
  83. */
  84. public static function DelCache($datakey)
  85. {
  86. self::CheckKey();
  87. unset($_SESSION[self::$_sessKey][self::$useRawKey ? $datakey : md5($datakey)]);
  88. }
  89. /**
  90. * Deletes all cached data using this class.
  91. */
  92. public static function DelAllCache()
  93. {
  94. self::CheckKey();
  95. $_SESSION[self::$_sessKey] = array();
  96. }
  97. /**
  98. * Returns the $_SESSION key that its beeing used to cache the data,
  99. * that by default will be 'SessCacher' (unless you changed it).
  100. */
  101. public static function GetSessKey()
  102. {
  103. return self::$_sessKey;
  104. }
  105. /**
  106. * Sets the $_SESSION key that its beeing used to cache the data.
  107. * No cached data will be lost by changing the key.
  108. *
  109. * $newKey: The new $_SESSION key
  110. */
  111. public static function SetSessKey($newKey)
  112. {
  113. $newKey = (string)$newKey;
  114. if($newKey == '' || self::$_sessKey == $newKey) return;
  115.  
  116. self::CheckKey();
  117.  
  118. $_SESSION[$newKey] = $_SESSION[self::$_sessKey];
  119. unset($_SESSION[self::$_sessKey]);
  120. self::$_sessKey = $newKey;
  121. }
  122. ////////////////////////////////////////////////////////////////////
  123. //PRIVATES
  124. ////////////////////////////////////////////////////////////////////
  125. private static function CheckKey()
  126. {
  127. if(!isset($_SESSION)) session_start();
  128. if(!array_key_exists(self::$_sessKey, $_SESSION)) $_SESSION[self::$_sessKey] = array();
  129. }
  130. }
  131.  
  132. //How to use
  133. $init_time = microtime(true);//Init measuring the total time taken to get the results
  134.  
  135. $in_cache = true;
  136.  
  137. //COUNT queries might take a long time
  138. $query = "SELECT COUNT(*) FROM huge_table";
  139.  
  140. //Here i am using the query as a unique key(string) to identify the cached data
  141. $results = SessCacher::GetCache($query);
  142. if($results === null)
  143. {
  144. $in_cache = false;
  145.  
  146. //If the SessCacher returned null it means that
  147. //the result is not cached an we have to retreive
  148. //it from the database
  149.  
  150. //$mysqli_link: the mysqli database link
  151. $mysqli_result = mysqli_query($mysqli_link, $query);
  152.  
  153. //We will put the fetched results into an array to cache them.
  154. $results = array();
  155. while($row = mysqli_fetch_assoc($mysqli_result))
  156. {
  157. array_push($results, $row);
  158. }
  159.  
  160. //Here i cache the results using the query as a key
  161. //and specifing that i want to reuse the cache
  162. //no more than 5 times
  163. SessCacher::SetCache($query, $results, 5);
  164. }
  165.  
  166. //The total time taken to retreive the results from cache or database in milliseconds
  167. $total_time = (string)round((microtime(true) - $init_time) * 1000, 2);
  168.  
  169.  
  170. //Echoing for testing purposes:
  171.  
  172. //Total time taken to get results
  173. echo 'total time taken ' .
  174. ($in_cache ? '(results from cache): ' : '(results from database): ') .
  175. $total_time . ' milliseconds';
  176. echo '<br />';
  177. echo '<pre>';
  178. print_r($results);
  179. echo '</pre>';
  180. ?>

Report this snippet  

You need to login to post a comment.