msession.php 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. <?php
  2. // +----------------------------------------------------------------------+
  3. // | PEAR :: Cache |
  4. // +----------------------------------------------------------------------+
  5. // | Copyright (c) 1997-2003 The PHP Group |
  6. // +----------------------------------------------------------------------+
  7. // | This source file is subject to version 2.0 of the PHP license, |
  8. // | that is bundled with this package in the file LICENSE, and is |
  9. // | available at through the world-wide-web at |
  10. // | http://www.php.net/license/2_02.txt. |
  11. // | If you did not receive a copy of the PHP license and are unable to |
  12. // | obtain it through the world-wide-web, please send a note to |
  13. // | license@php.net so we can mail you a copy immediately. |
  14. // +----------------------------------------------------------------------+
  15. // | Authors: Ulf Wendel <ulf.wendel@phpdoc.de> |
  16. // +----------------------------------------------------------------------+
  17. //
  18. // $Id: msession.php,v 1.4 2003/01/04 11:54:46 mj Exp $
  19. require_once 'Cache/Container.php';
  20. /**
  21. * Stores cache contents in msessions.
  22. *
  23. * WARNING: experimental, untested
  24. *
  25. * @author Ulf Wendel <ulf.wendel@phpdoc.de>
  26. * @version $Id: msession.php,v 1.4 2003/01/04 11:54:46 mj Exp $
  27. */
  28. class Cache_Container_msession extends Cache_Container {
  29. /**
  30. * Length of the Cache-Identifier
  31. *
  32. * Note that the PEAR-Cache prefixes the ID with an md5() value
  33. * of the cache-group. A good value for the id_length
  34. * depends on the maximum number of entries per cache group.
  35. *
  36. * @var int
  37. */
  38. var $id_length = 32;
  39. /**
  40. * Use msession_uniq to create a unique SID.
  41. *
  42. * @var boolean
  43. */
  44. var $uniq = true;
  45. /**
  46. * Establish a connection to a msession server?
  47. *
  48. * @var boolean
  49. */
  50. var $connect = true;
  51. /**
  52. * msession host
  53. *
  54. * @var string
  55. */
  56. var $host = NULL;
  57. /**
  58. * msession port
  59. *
  60. * @var string
  61. */
  62. var $port = NULL;
  63. /**
  64. * mesession server connection
  65. *
  66. * @var resource msession
  67. */
  68. var $ms = NULL;
  69. function Cache_Container_msession($options = '') {
  70. if (is_array($options))
  71. $this->setOptions($options, array_merge($this->allowed_options, array('id_lenght', 'uniq', 'host', 'port', 'connect')));
  72. if ($connect) {
  73. if (NULL == $this->host)
  74. new Cache_Error('No host specified.', __FILE__, __LINE__);
  75. if (NULL == $this->port)
  76. new Cache_Error('No port specified.', __FILE__, __LINE__);
  77. if (!($this->ms = msession_connect($this->host, $this->port)))
  78. new Cache_Error('Can not connect to the sever using host "' . $this->host . '" on port "' . $this->port . '"', __FILE__, __LINE__);
  79. }
  80. } // end func contructor
  81. function fetch($id, $group) {
  82. $id = strtoupper(md5($group)) . $id;
  83. $group = msession_get($id, '_pear_cache_data', NULL);
  84. if (NULL == $data)
  85. return array(NULL, NULL, NULL);
  86. return array($data['expires'], $data['cachedata'], $data['userdata']);
  87. } // end func fetch
  88. /**
  89. * Stores a dataset.
  90. *
  91. * WARNING: If you supply userdata it must not contain any linebreaks,
  92. * otherwise it will break the filestructure.
  93. */
  94. function save($id, $cachedata, $expires, $group, $userdata) {
  95. $this->flushPreload($id, $group);
  96. $cachedata = $this->encode($cachedata);
  97. $expires_abs = $this->getExpiresAbsolute($expires);
  98. $size = 1 + strlen($cachedata) + strlen($expires_abs) + strlen($userdata) + strlen($group);
  99. $size += strlen($size);
  100. $data = array(
  101. 'cachedata' => $cachedata,
  102. 'expires' => $expires_abs,
  103. 'userdata' => $userdata
  104. );
  105. $id = strtoupper(md5($group)) . $id;
  106. msession_lock($id);
  107. if (!msession_set($id, '_pear_cache', true)) {
  108. msession_unlock($id);
  109. return new Cache_Error("Can't write cache data.", __FILE__, __LINE__);
  110. }
  111. if (!msession_set($id, '_pear_cache_data', $data)) {
  112. msession_unlock($id);
  113. return new Cache_Error("Can't write cache data.", __FILE__, __LINE__);
  114. }
  115. if (!msession_set($id, '_pear_cache_group', $group)) {
  116. msession_unlock($id);
  117. return new Cache_Error("Can't write cache data.", __FILE__, __LINE__);
  118. }
  119. if (!msession_set($id, '_pear_cache_size', $size)) {
  120. msession_unlock($id);
  121. return new Cache_Error("Can't write cache data.", __FILE__, __LINE__);
  122. }
  123. // let msession do some GC as well
  124. // note that msession works different from the PEAR Cache.
  125. // msession deletes an entry if it has not been used for n-seconds.
  126. // PEAR Cache deletes after n-seconds.
  127. if (0 != $expires)
  128. msession_timeout($id, $expires);
  129. msession_unlock($id);
  130. return true;
  131. } // end func save
  132. function remove($id, $group) {
  133. $this->flushPreload($id, $group);
  134. return msession_destroy(strtoupper(md5($group)) . $id);
  135. } // end func remove
  136. function flush($group) {
  137. $this->flushPreload();
  138. $sessions = msession_find('_pear_cache_group', $group);
  139. if (empty($sessions))
  140. return 0;
  141. foreach ($sessions as $k => $id)
  142. messsion_destroy($id);
  143. return count($sessions);
  144. } // end func flush
  145. function idExists($id, $group) {
  146. return (NULL == msession_get(strtoupper(md5($group)) . $id, '_pear_cache_group', NULL)) ? false : true;
  147. } // end func idExists
  148. /**
  149. * Deletes all expired files.
  150. *
  151. * Note: garbage collection should cause lot's of network traffic.
  152. *
  153. * @param integer Maximum lifetime in seconds of an no longer used/touched entry
  154. * @throws Cache_Error
  155. */
  156. function garbageCollection($maxlifetime) {
  157. $this->flushPreload();
  158. $sessions = msession_find('_pear_cache', true);
  159. if (empty($sessions))
  160. return true;
  161. $total = 0;
  162. $entries = array();
  163. foreach ($sessions as $k => $id) {
  164. $data = msession_get($id, '_pear_cache_data', NULL);
  165. if (NULL == $data)
  166. continue;
  167. if ($data['expires'] <= time()) {
  168. msession_destroy($id);
  169. continue;
  170. }
  171. $size = msession_get($id, '_pear_cache_size', NULL);
  172. $total += $size;
  173. $entries[$data['expires']] = array($id, $size);
  174. }
  175. if ($total > $this->highwater) {
  176. krsort($entries);
  177. reset($entries);
  178. while ($total > $this->lowwater && list($expires, $entry) = each($entries)) {
  179. msession_destroy($entry[0]);
  180. $total -= $entry[1];
  181. }
  182. }
  183. return true;
  184. } // end func garbageCollection
  185. } // end class file
  186. ?>