Session.php 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. <?php
  2. namespace RocketTheme\Toolbox\Session;
  3. /**
  4. * Implements Session handling.
  5. *
  6. * @package RocketTheme\Toolbox\Session
  7. * @author RocketTheme
  8. * @license MIT
  9. */
  10. class Session implements \IteratorAggregate
  11. {
  12. /**
  13. * @var bool
  14. */
  15. protected $started = false;
  16. /**
  17. * @var Session
  18. */
  19. protected static $instance;
  20. /**
  21. * @param int $lifetime Defaults to 1800 seconds.
  22. * @param string $path Cookie path.
  23. * @param string $domain Optional, domain for the session
  24. * @throws \RuntimeException
  25. */
  26. public function __construct($lifetime, $path, $domain = null)
  27. {
  28. // Session is a singleton.
  29. if (isset(self::$instance)) {
  30. throw new \RuntimeException("Session has already been initialized.", 500);
  31. }
  32. // Destroy any existing sessions started with session.auto_start
  33. if ($this->isSessionStarted())
  34. {
  35. session_unset();
  36. session_destroy();
  37. }
  38. // Disable transparent sid support
  39. ini_set('session.use_trans_sid', 0);
  40. // Only allow cookies
  41. ini_set('session.use_cookies', 1);
  42. session_name('msF9kJcW');
  43. session_set_cookie_params($lifetime, $path, $domain);
  44. register_shutdown_function([$this, 'close']);
  45. session_cache_limiter('nocache');
  46. if (isset($this->count)) {
  47. $this->count++;
  48. } else {
  49. $this->count = 1;
  50. }
  51. self::$instance = $this;
  52. }
  53. /**
  54. * Get current session instance.
  55. *
  56. * @return Session
  57. * @throws \RuntimeException
  58. */
  59. public function instance()
  60. {
  61. if (!isset(self::$instance)) {
  62. throw new \RuntimeException("Session hasn't been initialized.", 500);
  63. }
  64. return self::$instance;
  65. }
  66. /**
  67. * Starts the session storage
  68. *
  69. * @return $this
  70. * @throws \RuntimeException
  71. */
  72. public function start()
  73. {
  74. // Protection against invalid session cookie names throwing exception: http://php.net/manual/en/function.session-id.php#116836
  75. if (isset($_COOKIE[session_name()]) && !preg_match('/^[-,a-zA-Z0-9]{1,128}$/', $_COOKIE[session_name()])) {
  76. unset($_COOKIE[session_name()]);
  77. }
  78. if (!session_start()) {
  79. throw new \RuntimeException('Failed to start session.', 500);
  80. }
  81. $this->started = true;
  82. return $this;
  83. }
  84. /**
  85. * Get session ID
  86. *
  87. * @return string Session ID
  88. */
  89. public function getId()
  90. {
  91. return session_id();
  92. }
  93. /**
  94. * Set session Id
  95. *
  96. * @param string $id Session ID
  97. *
  98. * @return $this
  99. */
  100. public function setId($id)
  101. {
  102. session_id($id);
  103. return $this;
  104. }
  105. /**
  106. * Get session name
  107. *
  108. * @return string
  109. */
  110. public function getName()
  111. {
  112. return session_name();
  113. }
  114. /**
  115. * Set session name
  116. *
  117. * @param string $name
  118. *
  119. * @return $this
  120. */
  121. public function setName($name)
  122. {
  123. session_name($name);
  124. return $this;
  125. }
  126. /**
  127. * Invalidates the current session.
  128. *
  129. * @return $this
  130. */
  131. public function invalidate()
  132. {
  133. $params = session_get_cookie_params();
  134. setcookie(session_name(), '', time() - 42000,
  135. $params['path'], $params['domain'],
  136. $params['secure'], $params['httponly']
  137. );
  138. session_unset();
  139. session_destroy();
  140. $this->started = false;
  141. return $this;
  142. }
  143. /**
  144. * Force the session to be saved and closed
  145. *
  146. * @return $this
  147. */
  148. public function close()
  149. {
  150. if ($this->started) {
  151. session_write_close();
  152. }
  153. $this->started = false;
  154. return $this;
  155. }
  156. /**
  157. * Checks if an attribute is defined.
  158. *
  159. * @param string $name The attribute name
  160. *
  161. * @return bool True if the attribute is defined, false otherwise
  162. */
  163. public function __isset($name)
  164. {
  165. return isset($_SESSION[$name]);
  166. }
  167. /**
  168. * Returns an attribute.
  169. *
  170. * @param string $name The attribute name
  171. *
  172. * @return mixed
  173. */
  174. public function __get($name)
  175. {
  176. return isset($_SESSION[$name]) ? $_SESSION[$name] : null;
  177. }
  178. /**
  179. * Sets an attribute.
  180. *
  181. * @param string $name
  182. * @param mixed $value
  183. */
  184. public function __set($name, $value)
  185. {
  186. $_SESSION[$name] = $value;
  187. }
  188. /**
  189. * Removes an attribute.
  190. *
  191. * @param string $name
  192. */
  193. public function __unset($name)
  194. {
  195. unset($_SESSION[$name]);
  196. }
  197. /**
  198. * Returns attributes.
  199. *
  200. * @return array Attributes
  201. */
  202. public function all()
  203. {
  204. return $_SESSION;
  205. }
  206. /**
  207. * Retrieve an external iterator
  208. *
  209. * @return \ArrayIterator Return an ArrayIterator of $_SESSION
  210. */
  211. public function getIterator()
  212. {
  213. return new \ArrayIterator($_SESSION);
  214. }
  215. /**
  216. * Checks if the session was started.
  217. *
  218. * @return Boolean
  219. */
  220. public function started()
  221. {
  222. return $this->started;
  223. }
  224. /**
  225. * http://php.net/manual/en/function.session-status.php#113468
  226. * Check if session is started nicely.
  227. * @return bool
  228. */
  229. protected function isSessionStarted()
  230. {
  231. return php_sapi_name() !== 'cli' ? session_id() !== '' : false;
  232. }
  233. }