/classes/kohana/session.php

https://github.com/misa/core · PHP · 415 lines · 160 code · 50 blank · 205 comment · 13 complexity · a2aac776a087da68e6e209a4399735d0 MD5 · raw file

  1. <?php defined('SYSPATH') or die('No direct script access.');
  2. /**
  3. * Base session class.
  4. *
  5. * @package Kohana
  6. * @category Session
  7. * @author Kohana Team
  8. * @copyright (c) 2008-2010 Kohana Team
  9. * @license http://kohanaframework.org/license
  10. */
  11. abstract class Kohana_Session {
  12. /**
  13. * @var string default session adapter
  14. */
  15. public static $default = 'native';
  16. // Session instances
  17. protected static $instances = array();
  18. /**
  19. * Creates a singleton session of the given type. Some session types
  20. * (native, database) also support restarting a session by passing a
  21. * session id as the second parameter.
  22. *
  23. * $session = Session::instance();
  24. *
  25. * [!!] [Session::write] will automatically be called when the request ends.
  26. *
  27. * @param string type of session (native, cookie, etc)
  28. * @param string session identifier
  29. * @return Session
  30. * @uses Kohana::config
  31. */
  32. public static function instance($type = NULL, $id = NULL)
  33. {
  34. if ($type === NULL)
  35. {
  36. // Use the default type
  37. $type = Session::$default;
  38. }
  39. if ( ! isset(Session::$instances[$type]))
  40. {
  41. // Load the configuration for this type
  42. $config = Kohana::config('session')->get($type);
  43. // Set the session class name
  44. $class = 'Session_'.ucfirst($type);
  45. // Create a new session instance
  46. Session::$instances[$type] = $session = new $class($config, $id);
  47. // Write the session at shutdown
  48. register_shutdown_function(array($session, 'write'));
  49. }
  50. return Session::$instances[$type];
  51. }
  52. // Cookie name
  53. protected $_name = 'session';
  54. // Cookie lifetime
  55. protected $_lifetime = 0;
  56. // Encrypt session data?
  57. protected $_encrypted = FALSE;
  58. // Session data
  59. protected $_data = array();
  60. // Is the session destroyed?
  61. protected $_destroyed = FALSE;
  62. /**
  63. * Overloads the name, lifetime, and encrypted session settings.
  64. *
  65. * [!!] Sessions can only be created using the [Session::instance] method.
  66. *
  67. * @param array configuration
  68. * @param string session id
  69. * @return void
  70. * @uses Session::read
  71. */
  72. public function __construct(array $config = NULL, $id = NULL)
  73. {
  74. if (isset($config['name']))
  75. {
  76. // Cookie name to store the session id in
  77. $this->_name = (string) $config['name'];
  78. }
  79. if (isset($config['lifetime']))
  80. {
  81. // Cookie lifetime
  82. $this->_lifetime = (int) $config['lifetime'];
  83. }
  84. if (isset($config['encrypted']))
  85. {
  86. if ($config['encrypted'] === TRUE)
  87. {
  88. // Use the default Encrypt instance
  89. $config['encrypted'] = 'default';
  90. }
  91. // Enable or disable encryption of data
  92. $this->_encrypted = $config['encrypted'];
  93. }
  94. // Load the session
  95. $this->read($id);
  96. }
  97. /**
  98. * Session object is rendered to a serialized string. If encryption is
  99. * enabled, the session will be encrypted. If not, the output string will
  100. * be encoded using [base64_encode].
  101. *
  102. * echo $session;
  103. *
  104. * @return string
  105. * @uses Encrypt::encode
  106. */
  107. public function __toString()
  108. {
  109. // Serialize the data array
  110. $data = serialize($this->_data);
  111. if ($this->_encrypted)
  112. {
  113. // Encrypt the data using the default key
  114. $data = Encrypt::instance($this->_encrypted)->encode($data);
  115. }
  116. else
  117. {
  118. // Obfuscate the data with base64 encoding
  119. $data = base64_encode($data);
  120. }
  121. return $data;
  122. }
  123. /**
  124. * Returns the current session array. The returned array can also be
  125. * assigned by reference.
  126. *
  127. * // Get a copy of the current session data
  128. * $data = $session->as_array();
  129. *
  130. * // Assign by reference for modification
  131. * $data =& $session->as_array();
  132. *
  133. * @return array
  134. */
  135. public function & as_array()
  136. {
  137. return $this->_data;
  138. }
  139. /**
  140. * Get the current session id, if the session supports it.
  141. *
  142. * $id = $session->id();
  143. *
  144. * [!!] Not all session types have ids.
  145. *
  146. * @return string
  147. * @since 3.0.8
  148. */
  149. public function id()
  150. {
  151. return NULL;
  152. }
  153. /**
  154. * Get the current session cookie name.
  155. *
  156. * $name = $session->name();
  157. *
  158. * @return string
  159. * @since 3.0.8
  160. */
  161. public function name()
  162. {
  163. return $this->_name;
  164. }
  165. /**
  166. * Get a variable from the session array.
  167. *
  168. * $foo = $session->get('foo');
  169. *
  170. * @param string variable name
  171. * @param mixed default value to return
  172. * @return mixed
  173. */
  174. public function get($key, $default = NULL)
  175. {
  176. return array_key_exists($key, $this->_data) ? $this->_data[$key] : $default;
  177. }
  178. /**
  179. * Get and delete a variable from the session array.
  180. *
  181. * $bar = $session->get_once('bar');
  182. *
  183. * @param string variable name
  184. * @param mixed default value to return
  185. * @return mixed
  186. */
  187. public function get_once($key, $default = NULL)
  188. {
  189. $value = $this->get($key, $default);
  190. unset($this->_data[$key]);
  191. return $value;
  192. }
  193. /**
  194. * Set a variable in the session array.
  195. *
  196. * $session->set('foo', 'bar');
  197. *
  198. * @param string variable name
  199. * @param mixed value
  200. * @return $this
  201. */
  202. public function set($key, $value)
  203. {
  204. $this->_data[$key] = $value;
  205. return $this;
  206. }
  207. /**
  208. * Set a variable by reference.
  209. *
  210. * $session->bind('foo', $foo);
  211. *
  212. * @param string variable name
  213. * @param mixed referenced value
  214. * @return $this
  215. */
  216. public function bind($key, & $value)
  217. {
  218. $this->_data[$key] =& $value;
  219. return $this;
  220. }
  221. /**
  222. * Removes a variable in the session array.
  223. *
  224. * $session->delete('foo');
  225. *
  226. * @param string variable name
  227. * @param ...
  228. * @return $this
  229. */
  230. public function delete($key)
  231. {
  232. $args = func_get_args();
  233. foreach ($args as $key)
  234. {
  235. unset($this->_data[$key]);
  236. }
  237. return $this;
  238. }
  239. /**
  240. * Loads existing session data.
  241. *
  242. * $session->read();
  243. *
  244. * @param string session id
  245. * @return void
  246. */
  247. public function read($id = NULL)
  248. {
  249. if (is_string($data = $this->_read($id)))
  250. {
  251. try
  252. {
  253. if ($this->_encrypted)
  254. {
  255. // Decrypt the data using the default key
  256. $data = Encrypt::instance($this->_encrypted)->decode($data);
  257. }
  258. else
  259. {
  260. // Decode the base64 encoded data
  261. $data = base64_decode($data);
  262. }
  263. // Unserialize the data
  264. $data = unserialize($data);
  265. }
  266. catch (Exception $e)
  267. {
  268. // Ignore all reading errors
  269. }
  270. }
  271. if (is_array($data))
  272. {
  273. // Load the data locally
  274. $this->_data = $data;
  275. }
  276. }
  277. /**
  278. * Generates a new session id and returns it.
  279. *
  280. * $id = $session->regenerate();
  281. *
  282. * @return string
  283. */
  284. public function regenerate()
  285. {
  286. return $this->_regenerate();
  287. }
  288. /**
  289. * Sets the last_active timestamp and saves the session.
  290. *
  291. * $session->write();
  292. *
  293. * [!!] Any errors that occur during session writing will be logged,
  294. * but not displayed, because sessions are written after output has
  295. * been sent.
  296. *
  297. * @return boolean
  298. * @uses Kohana::$log
  299. */
  300. public function write()
  301. {
  302. if (headers_sent() OR $this->_destroyed)
  303. {
  304. // Session cannot be written when the headers are sent or when
  305. // the session has been destroyed
  306. return FALSE;
  307. }
  308. // Set the last active timestamp
  309. $this->_data['last_active'] = time();
  310. try
  311. {
  312. return $this->_write();
  313. }
  314. catch (Exception $e)
  315. {
  316. // Log & ignore all errors when a write fails
  317. Kohana::$log->add(Kohana::ERROR, Kohana::exception_text($e))->write();
  318. return FALSE;
  319. }
  320. }
  321. /**
  322. * Completely destroy the current session.
  323. *
  324. * $success = $session->destroy();
  325. *
  326. * @return boolean
  327. */
  328. public function destroy()
  329. {
  330. if ($this->_destroyed === FALSE)
  331. {
  332. if ($this->_destroyed = $this->_destroy())
  333. {
  334. // The session has been destroyed, clear all data
  335. $this->_data = array();
  336. }
  337. }
  338. return $this->_destroyed;
  339. }
  340. /**
  341. * Loads the raw session data string and returns it.
  342. *
  343. * @param string session id
  344. * @return string
  345. */
  346. abstract protected function _read($id = NULL);
  347. /**
  348. * Generate a new session id and return it.
  349. *
  350. * @return string
  351. */
  352. abstract protected function _regenerate();
  353. /**
  354. * Writes the current session.
  355. *
  356. * @return boolean
  357. */
  358. abstract protected function _write();
  359. /**
  360. * Destroys the current session.
  361. *
  362. * @return boolean
  363. */
  364. abstract protected function _destroy();
  365. } // End Session