/src/DALMP/Sessions/Redis.php

https://github.com/nbari/DALMP · PHP · 211 lines · 117 code · 32 blank · 62 comment · 18 complexity · 8642b694e1ba24540d6df10547f09410 MD5 · raw file

  1. <?php
  2. namespace DALMP\Sessions;
  3. /**
  4. * Sessions\Redis
  5. *
  6. * @author Nicolas Embriz <nbari@dalmp.com>
  7. * @package DALMP
  8. * @license BSD License
  9. * @version 3.0.3
  10. */
  11. class Redis implements \SessionHandlerInterface
  12. {
  13. /**
  14. * DALMP\Cache\Redis instance
  15. *
  16. * @access protected
  17. * @var DALMP\Cache\Redis
  18. */
  19. protected $cache;
  20. /**
  21. * cache_ref_key key used to store the reference on the cache engine
  22. *
  23. * @access private
  24. * @var string
  25. */
  26. private $cache_ref_key;
  27. /**
  28. * REF - field used for storing references
  29. *
  30. * @access private
  31. * @var mixed
  32. */
  33. private $dalmp_sessions_ref;
  34. /**
  35. * key used for creating more entropy when storing the sessions on a
  36. * key/value cache engine, useful when serving multiple sites
  37. *
  38. * @access private
  39. * @var mixed
  40. */
  41. private $dalmp_sessions_key;
  42. /**
  43. * constructor
  44. *
  45. * @param DALMP\Cache\Redis $cache instance
  46. * @param string $sessions_ref global variable to be stored as reference
  47. */
  48. public function __construct(\DALMP\Cache\Redis $cache, $sessions_ref = 'UID')
  49. {
  50. $this->cache = $cache;
  51. $this->dalmp_sessions_ref = defined('DALMP_SESSIONS_REF') ? DALMP_SESSIONS_REF : $sessions_ref;
  52. $this->dalmp_sessions_key = defined('DALMP_SESSIONS_KEY') ? DALMP_SESSIONS_KEY : __FILE__;
  53. $this->cache_ref_key = sprintf('DALMP_REF_%s', sha1($this->dalmp_sessions_ref . $this->dalmp_sessions_key));
  54. }
  55. public function close()
  56. {
  57. return true;
  58. }
  59. public function destroy($session_id)
  60. {
  61. $key = sprintf('DALMP_%s', sha1($this->dalmp_sessions_ref . $session_id));
  62. if ($rs = $this->cache->Delete($key)) {
  63. /**
  64. * destroy REF on cache
  65. */
  66. if (isset($GLOBALS[$this->dalmp_sessions_ref]) && !empty($GLOBALS[$this->dalmp_sessions_ref])) {
  67. $this->cache->X()->HDEL($this->cache_ref_key, $key);
  68. $this->cache->X()->EXPIRE($this->cache_ref_key, 3600);
  69. }
  70. return true;
  71. } else {
  72. return false;
  73. }
  74. }
  75. public function gc($maxlifetime)
  76. {
  77. $refs = $this->cache->X()->HGETALL($this->cache_ref_key);
  78. $keys = array($this->cache_ref_key);
  79. if (is_array($refs)) {
  80. foreach ($refs as $key => $sref) {
  81. $data = explode('|', $sref);
  82. if (current($data) < time()) {
  83. $keys[] = $key;
  84. }
  85. }
  86. if (count($keys) > 1) {
  87. $redis = $this->cache->X();
  88. call_user_func_array(array($redis, 'HDEL'), $keys);
  89. $this->cache->X()->EXPIRE($this->cache_ref_key, 3600);
  90. }
  91. }
  92. return true;
  93. }
  94. public function open($save_path, $name)
  95. {
  96. return true;
  97. }
  98. public function read($session_id)
  99. {
  100. $key = sprintf('DALMP_%s', sha1($this->dalmp_sessions_ref . $session_id));
  101. return $this->cache->Get($key);
  102. }
  103. public function write($session_id, $session_data)
  104. {
  105. $ref = (isset($GLOBALS[$this->dalmp_sessions_ref]) && !empty($GLOBALS[$this->dalmp_sessions_ref])) ? $GLOBALS[$this->dalmp_sessions_ref] : null;
  106. $timeout = ini_get('session.gc_maxlifetime');
  107. $expiry = time() + $timeout;
  108. $key = sprintf('DALMP_%s', sha1($this->dalmp_sessions_ref . $session_id));
  109. $rs = (bool) $this->cache->Set($key, $session_data, $timeout);
  110. /**
  111. * store REF on cache
  112. */
  113. if ($rs && $ref) {
  114. return (bool) ($this->cache->X()->HSET($this->cache_ref_key, $key, sprintf('%s|%s', $ref, $expiry)) ? $this->cache->X()->EXPIRE($this->cache_ref_key, 3600) : false);
  115. } else {
  116. return $rs;
  117. }
  118. }
  119. /**
  120. * getSessionsRefs
  121. *
  122. * @return array of sessions containing any reference
  123. */
  124. public function getSessionsRefs()
  125. {
  126. $refs = $this->cache->X()->HGetALL($this->cache_ref_key);
  127. $rs = array();
  128. foreach ($refs as $key => $data) {
  129. list($reference, $expiry) = explode('|', $data);
  130. $rs[$key] = array($reference => $expiry);
  131. }
  132. return $rs;
  133. }
  134. /**
  135. * getSessionRef
  136. *
  137. * @param string $ref
  138. * @return array of session containing a specific reference
  139. */
  140. public function getSessionRef($ref)
  141. {
  142. $refs = $this->cache->X()->HGetALL($this->cache_ref_key);
  143. $rs = array();
  144. foreach ($refs as $key => $data) {
  145. list($reference, $expiry) = explode('|', $data);
  146. if ($reference == $ref) {
  147. $rs[$key] = array($reference => $expiry);
  148. }
  149. }
  150. return $rs;
  151. }
  152. /**
  153. * delSessionRef - delete sessions containing a specific reference
  154. *
  155. * @param string $ref
  156. * @return boolean
  157. */
  158. public function delSessionRef($ref)
  159. {
  160. $refs = $this->cache->X()->HGETALL($this->cache_ref_key);
  161. $keys = array($this->cache_ref_key);
  162. if (is_array($refs)) {
  163. foreach ($refs as $key => $data) {
  164. list($reference, $expiry) = explode('|', $data);
  165. if ($reference == $ref) {
  166. $keys[] = $key;
  167. }
  168. }
  169. }
  170. if (count($keys) > 1) {
  171. $redis = $this->cache->X();
  172. call_user_func_array(array($redis, 'HDEL'), $keys);
  173. array_shift($keys);
  174. return (bool) $this->cache->delete($keys);
  175. } else {
  176. return false;
  177. }
  178. }
  179. }