Session.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983
  1. <?php
  2. /**
  3. * CodeIgniter
  4. *
  5. * An open source application development framework for PHP
  6. *
  7. * This content is released under the MIT License (MIT)
  8. *
  9. * Copyright (c) 2014 - 2019, British Columbia Institute of Technology
  10. *
  11. * Permission is hereby granted, free of charge, to any person obtaining a copy
  12. * of this software and associated documentation files (the "Software"), to deal
  13. * in the Software without restriction, including without limitation the rights
  14. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  15. * copies of the Software, and to permit persons to whom the Software is
  16. * furnished to do so, subject to the following conditions:
  17. *
  18. * The above copyright notice and this permission notice shall be included in
  19. * all copies or substantial portions of the Software.
  20. *
  21. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  22. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  23. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  24. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  25. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  26. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  27. * THE SOFTWARE.
  28. *
  29. * @package CodeIgniter
  30. * @author EllisLab Dev Team
  31. * @copyright Copyright (c) 2008 - 2014, EllisLab, Inc. (https://ellislab.com/)
  32. * @copyright Copyright (c) 2014 - 2019, British Columbia Institute of Technology (https://bcit.ca/)
  33. * @license https://opensource.org/licenses/MIT MIT License
  34. * @link https://codeigniter.com
  35. * @since Version 2.0.0
  36. * @filesource
  37. */
  38. defined('BASEPATH') OR exit('No direct script access allowed');
  39. /**
  40. * CodeIgniter Session Class
  41. *
  42. * @package CodeIgniter
  43. * @subpackage Libraries
  44. * @category Sessions
  45. * @author Andrey Andreev
  46. * @link https://codeigniter.com/user_guide/libraries/sessions.html
  47. */
  48. class CI_Session {
  49. /**
  50. * Userdata array
  51. *
  52. * Just a reference to $_SESSION, for BC purposes.
  53. */
  54. public $userdata;
  55. protected $_driver = 'files';
  56. protected $_config;
  57. protected $_sid_regexp;
  58. // ------------------------------------------------------------------------
  59. /**
  60. * Class constructor
  61. *
  62. * @param array $params Configuration parameters
  63. * @return void
  64. */
  65. public function __construct(array $params = array())
  66. {
  67. // No sessions under CLI
  68. if (is_cli())
  69. {
  70. log_message('debug', 'Session: Initialization under CLI aborted.');
  71. return;
  72. }
  73. elseif ((bool) ini_get('session.auto_start'))
  74. {
  75. log_message('error', 'Session: session.auto_start is enabled in php.ini. Aborting.');
  76. return;
  77. }
  78. elseif ( ! empty($params['driver']))
  79. {
  80. $this->_driver = $params['driver'];
  81. unset($params['driver']);
  82. }
  83. elseif ($driver = config_item('sess_driver'))
  84. {
  85. $this->_driver = $driver;
  86. }
  87. // Note: BC workaround
  88. elseif (config_item('sess_use_database'))
  89. {
  90. log_message('debug', 'Session: "sess_driver" is empty; using BC fallback to "sess_use_database".');
  91. $this->_driver = 'database';
  92. }
  93. $class = $this->_ci_load_classes($this->_driver);
  94. // Configuration ...
  95. $this->_configure($params);
  96. $this->_config['_sid_regexp'] = $this->_sid_regexp;
  97. $class = new $class($this->_config);
  98. if ($class instanceof SessionHandlerInterface)
  99. {
  100. if (is_php('5.4'))
  101. {
  102. session_set_save_handler($class, TRUE);
  103. }
  104. else
  105. {
  106. session_set_save_handler(
  107. array($class, 'open'),
  108. array($class, 'close'),
  109. array($class, 'read'),
  110. array($class, 'write'),
  111. array($class, 'destroy'),
  112. array($class, 'gc')
  113. );
  114. register_shutdown_function('session_write_close');
  115. }
  116. }
  117. else
  118. {
  119. log_message('error', "Session: Driver '".$this->_driver."' doesn't implement SessionHandlerInterface. Aborting.");
  120. return;
  121. }
  122. // Sanitize the cookie, because apparently PHP doesn't do that for userspace handlers
  123. if (isset($_COOKIE[$this->_config['cookie_name']])
  124. && (
  125. ! is_string($_COOKIE[$this->_config['cookie_name']])
  126. OR ! preg_match('#\A'.$this->_sid_regexp.'\z#', $_COOKIE[$this->_config['cookie_name']])
  127. )
  128. )
  129. {
  130. unset($_COOKIE[$this->_config['cookie_name']]);
  131. }
  132. session_start();
  133. // Is session ID auto-regeneration configured? (ignoring ajax requests)
  134. if ((empty($_SERVER['HTTP_X_REQUESTED_WITH']) OR strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) !== 'xmlhttprequest')
  135. && ($regenerate_time = config_item('sess_time_to_update')) > 0
  136. )
  137. {
  138. if ( ! isset($_SESSION['__ci_last_regenerate']))
  139. {
  140. $_SESSION['__ci_last_regenerate'] = time();
  141. }
  142. elseif ($_SESSION['__ci_last_regenerate'] < (time() - $regenerate_time))
  143. {
  144. $this->sess_regenerate((bool) config_item('sess_regenerate_destroy'));
  145. }
  146. }
  147. // Another work-around ... PHP doesn't seem to send the session cookie
  148. // unless it is being currently created or regenerated
  149. elseif (isset($_COOKIE[$this->_config['cookie_name']]) && $_COOKIE[$this->_config['cookie_name']] === session_id())
  150. {
  151. setcookie(
  152. $this->_config['cookie_name'],
  153. session_id(),
  154. (empty($this->_config['cookie_lifetime']) ? 0 : time() + $this->_config['cookie_lifetime']),
  155. $this->_config['cookie_path'],
  156. $this->_config['cookie_domain'],
  157. $this->_config['cookie_secure'],
  158. TRUE
  159. );
  160. }
  161. $this->_ci_init_vars();
  162. log_message('info', "Session: Class initialized using '".$this->_driver."' driver.");
  163. }
  164. // ------------------------------------------------------------------------
  165. /**
  166. * CI Load Classes
  167. *
  168. * An internal method to load all possible dependency and extension
  169. * classes. It kind of emulates the CI_Driver library, but is
  170. * self-sufficient.
  171. *
  172. * @param string $driver Driver name
  173. * @return string Driver class name
  174. */
  175. protected function _ci_load_classes($driver)
  176. {
  177. // PHP 5.4 compatibility
  178. interface_exists('SessionHandlerInterface', FALSE) OR require_once(BASEPATH.'libraries/Session/SessionHandlerInterface.php');
  179. $prefix = config_item('subclass_prefix');
  180. if ( ! class_exists('CI_Session_driver', FALSE))
  181. {
  182. require_once(
  183. file_exists(APPPATH.'libraries/Session/Session_driver.php')
  184. ? APPPATH.'libraries/Session/Session_driver.php'
  185. : BASEPATH.'libraries/Session/Session_driver.php'
  186. );
  187. if (file_exists($file_path = APPPATH.'libraries/Session/'.$prefix.'Session_driver.php'))
  188. {
  189. require_once($file_path);
  190. }
  191. }
  192. $class = 'Session_'.$driver.'_driver';
  193. // Allow custom drivers without the CI_ or MY_ prefix
  194. if ( ! class_exists($class, FALSE) && file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$class.'.php'))
  195. {
  196. require_once($file_path);
  197. if (class_exists($class, FALSE))
  198. {
  199. return $class;
  200. }
  201. }
  202. if ( ! class_exists('CI_'.$class, FALSE))
  203. {
  204. if (file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$class.'.php') OR file_exists($file_path = BASEPATH.'libraries/Session/drivers/'.$class.'.php'))
  205. {
  206. require_once($file_path);
  207. }
  208. if ( ! class_exists('CI_'.$class, FALSE) && ! class_exists($class, FALSE))
  209. {
  210. throw new UnexpectedValueException("Session: Configured driver '".$driver."' was not found. Aborting.");
  211. }
  212. }
  213. if ( ! class_exists($prefix.$class, FALSE) && file_exists($file_path = APPPATH.'libraries/Session/drivers/'.$prefix.$class.'.php'))
  214. {
  215. require_once($file_path);
  216. if (class_exists($prefix.$class, FALSE))
  217. {
  218. return $prefix.$class;
  219. }
  220. log_message('debug', 'Session: '.$prefix.$class.".php found but it doesn't declare class ".$prefix.$class.'.');
  221. }
  222. return 'CI_'.$class;
  223. }
  224. // ------------------------------------------------------------------------
  225. /**
  226. * Configuration
  227. *
  228. * Handle input parameters and configuration defaults
  229. *
  230. * @param array &$params Input parameters
  231. * @return void
  232. */
  233. protected function _configure(&$params)
  234. {
  235. $expiration = config_item('sess_expiration');
  236. if (isset($params['cookie_lifetime']))
  237. {
  238. $params['cookie_lifetime'] = (int) $params['cookie_lifetime'];
  239. }
  240. else
  241. {
  242. $params['cookie_lifetime'] = ( ! isset($expiration) && config_item('sess_expire_on_close'))
  243. ? 0 : (int) $expiration;
  244. }
  245. isset($params['cookie_name']) OR $params['cookie_name'] = config_item('sess_cookie_name');
  246. if (empty($params['cookie_name']))
  247. {
  248. $params['cookie_name'] = ini_get('session.name');
  249. }
  250. else
  251. {
  252. ini_set('session.name', $params['cookie_name']);
  253. }
  254. isset($params['cookie_path']) OR $params['cookie_path'] = config_item('cookie_path');
  255. isset($params['cookie_domain']) OR $params['cookie_domain'] = config_item('cookie_domain');
  256. isset($params['cookie_secure']) OR $params['cookie_secure'] = (bool) config_item('cookie_secure');
  257. session_set_cookie_params(
  258. $params['cookie_lifetime'],
  259. $params['cookie_path'],
  260. $params['cookie_domain'],
  261. $params['cookie_secure'],
  262. TRUE // HttpOnly; Yes, this is intentional and not configurable for security reasons
  263. );
  264. if (empty($expiration))
  265. {
  266. $params['expiration'] = (int) ini_get('session.gc_maxlifetime');
  267. }
  268. else
  269. {
  270. $params['expiration'] = (int) $expiration;
  271. ini_set('session.gc_maxlifetime', $expiration);
  272. }
  273. $params['match_ip'] = (bool) (isset($params['match_ip']) ? $params['match_ip'] : config_item('sess_match_ip'));
  274. isset($params['save_path']) OR $params['save_path'] = config_item('sess_save_path');
  275. $this->_config = $params;
  276. // Security is king
  277. ini_set('session.use_trans_sid', 0);
  278. ini_set('session.use_strict_mode', 1);
  279. ini_set('session.use_cookies', 1);
  280. ini_set('session.use_only_cookies', 1);
  281. $this->_configure_sid_length();
  282. }
  283. // ------------------------------------------------------------------------
  284. /**
  285. * Configure session ID length
  286. *
  287. * To make life easier, we used to force SHA-1 and 4 bits per
  288. * character on everyone. And of course, someone was unhappy.
  289. *
  290. * Then PHP 7.1 broke backwards-compatibility because ext/session
  291. * is such a mess that nobody wants to touch it with a pole stick,
  292. * and the one guy who does, nobody has the energy to argue with.
  293. *
  294. * So we were forced to make changes, and OF COURSE something was
  295. * going to break and now we have this pile of shit. -- Narf
  296. *
  297. * @return void
  298. */
  299. protected function _configure_sid_length()
  300. {
  301. if (PHP_VERSION_ID < 70100)
  302. {
  303. $hash_function = ini_get('session.hash_function');
  304. if (ctype_digit($hash_function))
  305. {
  306. if ($hash_function !== '1')
  307. {
  308. ini_set('session.hash_function', 1);
  309. }
  310. $bits = 160;
  311. }
  312. elseif ( ! in_array($hash_function, hash_algos(), TRUE))
  313. {
  314. ini_set('session.hash_function', 1);
  315. $bits = 160;
  316. }
  317. elseif (($bits = strlen(hash($hash_function, 'dummy', false)) * 4) < 160)
  318. {
  319. ini_set('session.hash_function', 1);
  320. $bits = 160;
  321. }
  322. $bits_per_character = (int) ini_get('session.hash_bits_per_character');
  323. $sid_length = (int) ceil($bits / $bits_per_character);
  324. }
  325. else
  326. {
  327. $bits_per_character = (int) ini_get('session.sid_bits_per_character');
  328. $sid_length = (int) ini_get('session.sid_length');
  329. if (($bits = $sid_length * $bits_per_character) < 160)
  330. {
  331. // Add as many more characters as necessary to reach at least 160 bits
  332. $sid_length += (int) ceil((160 % $bits) / $bits_per_character);
  333. ini_set('session.sid_length', $sid_length);
  334. }
  335. }
  336. // Yes, 4,5,6 are the only known possible values as of 2016-10-27
  337. switch ($bits_per_character)
  338. {
  339. case 4:
  340. $this->_sid_regexp = '[0-9a-f]';
  341. break;
  342. case 5:
  343. $this->_sid_regexp = '[0-9a-v]';
  344. break;
  345. case 6:
  346. $this->_sid_regexp = '[0-9a-zA-Z,-]';
  347. break;
  348. }
  349. $this->_sid_regexp .= '{'.$sid_length.'}';
  350. }
  351. // ------------------------------------------------------------------------
  352. /**
  353. * Handle temporary variables
  354. *
  355. * Clears old "flash" data, marks the new one for deletion and handles
  356. * "temp" data deletion.
  357. *
  358. * @return void
  359. */
  360. protected function _ci_init_vars()
  361. {
  362. if ( ! empty($_SESSION['__ci_vars']))
  363. {
  364. $current_time = time();
  365. foreach ($_SESSION['__ci_vars'] as $key => &$value)
  366. {
  367. if ($value === 'new')
  368. {
  369. $_SESSION['__ci_vars'][$key] = 'old';
  370. }
  371. // Hacky, but 'old' will (implicitly) always be less than time() ;)
  372. // DO NOT move this above the 'new' check!
  373. elseif ($value < $current_time)
  374. {
  375. unset($_SESSION[$key], $_SESSION['__ci_vars'][$key]);
  376. }
  377. }
  378. if (empty($_SESSION['__ci_vars']))
  379. {
  380. unset($_SESSION['__ci_vars']);
  381. }
  382. }
  383. $this->userdata =& $_SESSION;
  384. }
  385. // ------------------------------------------------------------------------
  386. /**
  387. * Mark as flash
  388. *
  389. * @param mixed $key Session data key(s)
  390. * @return bool
  391. */
  392. public function mark_as_flash($key)
  393. {
  394. if (is_array($key))
  395. {
  396. for ($i = 0, $c = count($key); $i < $c; $i++)
  397. {
  398. if ( ! isset($_SESSION[$key[$i]]))
  399. {
  400. return FALSE;
  401. }
  402. }
  403. $new = array_fill_keys($key, 'new');
  404. $_SESSION['__ci_vars'] = isset($_SESSION['__ci_vars'])
  405. ? array_merge($_SESSION['__ci_vars'], $new)
  406. : $new;
  407. return TRUE;
  408. }
  409. if ( ! isset($_SESSION[$key]))
  410. {
  411. return FALSE;
  412. }
  413. $_SESSION['__ci_vars'][$key] = 'new';
  414. return TRUE;
  415. }
  416. // ------------------------------------------------------------------------
  417. /**
  418. * Get flash keys
  419. *
  420. * @return array
  421. */
  422. public function get_flash_keys()
  423. {
  424. if ( ! isset($_SESSION['__ci_vars']))
  425. {
  426. return array();
  427. }
  428. $keys = array();
  429. foreach (array_keys($_SESSION['__ci_vars']) as $key)
  430. {
  431. is_int($_SESSION['__ci_vars'][$key]) OR $keys[] = $key;
  432. }
  433. return $keys;
  434. }
  435. // ------------------------------------------------------------------------
  436. /**
  437. * Unmark flash
  438. *
  439. * @param mixed $key Session data key(s)
  440. * @return void
  441. */
  442. public function unmark_flash($key)
  443. {
  444. if (empty($_SESSION['__ci_vars']))
  445. {
  446. return;
  447. }
  448. is_array($key) OR $key = array($key);
  449. foreach ($key as $k)
  450. {
  451. if (isset($_SESSION['__ci_vars'][$k]) && ! is_int($_SESSION['__ci_vars'][$k]))
  452. {
  453. unset($_SESSION['__ci_vars'][$k]);
  454. }
  455. }
  456. if (empty($_SESSION['__ci_vars']))
  457. {
  458. unset($_SESSION['__ci_vars']);
  459. }
  460. }
  461. // ------------------------------------------------------------------------
  462. /**
  463. * Mark as temp
  464. *
  465. * @param mixed $key Session data key(s)
  466. * @param int $ttl Time-to-live in seconds
  467. * @return bool
  468. */
  469. public function mark_as_temp($key, $ttl = 300)
  470. {
  471. $ttl += time();
  472. if (is_array($key))
  473. {
  474. $temp = array();
  475. foreach ($key as $k => $v)
  476. {
  477. // Do we have a key => ttl pair, or just a key?
  478. if (is_int($k))
  479. {
  480. $k = $v;
  481. $v = $ttl;
  482. }
  483. else
  484. {
  485. $v += time();
  486. }
  487. if ( ! isset($_SESSION[$k]))
  488. {
  489. return FALSE;
  490. }
  491. $temp[$k] = $v;
  492. }
  493. $_SESSION['__ci_vars'] = isset($_SESSION['__ci_vars'])
  494. ? array_merge($_SESSION['__ci_vars'], $temp)
  495. : $temp;
  496. return TRUE;
  497. }
  498. if ( ! isset($_SESSION[$key]))
  499. {
  500. return FALSE;
  501. }
  502. $_SESSION['__ci_vars'][$key] = $ttl;
  503. return TRUE;
  504. }
  505. // ------------------------------------------------------------------------
  506. /**
  507. * Get temp keys
  508. *
  509. * @return array
  510. */
  511. public function get_temp_keys()
  512. {
  513. if ( ! isset($_SESSION['__ci_vars']))
  514. {
  515. return array();
  516. }
  517. $keys = array();
  518. foreach (array_keys($_SESSION['__ci_vars']) as $key)
  519. {
  520. is_int($_SESSION['__ci_vars'][$key]) && $keys[] = $key;
  521. }
  522. return $keys;
  523. }
  524. // ------------------------------------------------------------------------
  525. /**
  526. * Unmark temp
  527. *
  528. * @param mixed $key Session data key(s)
  529. * @return void
  530. */
  531. public function unmark_temp($key)
  532. {
  533. if (empty($_SESSION['__ci_vars']))
  534. {
  535. return;
  536. }
  537. is_array($key) OR $key = array($key);
  538. foreach ($key as $k)
  539. {
  540. if (isset($_SESSION['__ci_vars'][$k]) && is_int($_SESSION['__ci_vars'][$k]))
  541. {
  542. unset($_SESSION['__ci_vars'][$k]);
  543. }
  544. }
  545. if (empty($_SESSION['__ci_vars']))
  546. {
  547. unset($_SESSION['__ci_vars']);
  548. }
  549. }
  550. // ------------------------------------------------------------------------
  551. /**
  552. * __get()
  553. *
  554. * @param string $key 'session_id' or a session data key
  555. * @return mixed
  556. */
  557. public function __get($key)
  558. {
  559. // Note: Keep this order the same, just in case somebody wants to
  560. // use 'session_id' as a session data key, for whatever reason
  561. if (isset($_SESSION[$key]))
  562. {
  563. return $_SESSION[$key];
  564. }
  565. elseif ($key === 'session_id')
  566. {
  567. return session_id();
  568. }
  569. return NULL;
  570. }
  571. // ------------------------------------------------------------------------
  572. /**
  573. * __isset()
  574. *
  575. * @param string $key 'session_id' or a session data key
  576. * @return bool
  577. */
  578. public function __isset($key)
  579. {
  580. if ($key === 'session_id')
  581. {
  582. return (session_status() === PHP_SESSION_ACTIVE);
  583. }
  584. return isset($_SESSION[$key]);
  585. }
  586. // ------------------------------------------------------------------------
  587. /**
  588. * __set()
  589. *
  590. * @param string $key Session data key
  591. * @param mixed $value Session data value
  592. * @return void
  593. */
  594. public function __set($key, $value)
  595. {
  596. $_SESSION[$key] = $value;
  597. }
  598. // ------------------------------------------------------------------------
  599. /**
  600. * Session destroy
  601. *
  602. * Legacy CI_Session compatibility method
  603. *
  604. * @return void
  605. */
  606. public function sess_destroy()
  607. {
  608. session_destroy();
  609. }
  610. // ------------------------------------------------------------------------
  611. /**
  612. * Session regenerate
  613. *
  614. * Legacy CI_Session compatibility method
  615. *
  616. * @param bool $destroy Destroy old session data flag
  617. * @return void
  618. */
  619. public function sess_regenerate($destroy = FALSE)
  620. {
  621. $_SESSION['__ci_last_regenerate'] = time();
  622. session_regenerate_id($destroy);
  623. }
  624. // ------------------------------------------------------------------------
  625. /**
  626. * Get userdata reference
  627. *
  628. * Legacy CI_Session compatibility method
  629. *
  630. * @returns array
  631. */
  632. public function &get_userdata()
  633. {
  634. return $_SESSION;
  635. }
  636. // ------------------------------------------------------------------------
  637. /**
  638. * Userdata (fetch)
  639. *
  640. * Legacy CI_Session compatibility method
  641. *
  642. * @param string $key Session data key
  643. * @return mixed Session data value or NULL if not found
  644. */
  645. public function userdata($key = NULL)
  646. {
  647. if (isset($key))
  648. {
  649. return isset($_SESSION[$key]) ? $_SESSION[$key] : NULL;
  650. }
  651. elseif (empty($_SESSION))
  652. {
  653. return array();
  654. }
  655. $userdata = array();
  656. $_exclude = array_merge(
  657. array('__ci_vars'),
  658. $this->get_flash_keys(),
  659. $this->get_temp_keys()
  660. );
  661. foreach (array_keys($_SESSION) as $key)
  662. {
  663. if ( ! in_array($key, $_exclude, TRUE))
  664. {
  665. $userdata[$key] = $_SESSION[$key];
  666. }
  667. }
  668. return $userdata;
  669. }
  670. // ------------------------------------------------------------------------
  671. /**
  672. * Set userdata
  673. *
  674. * Legacy CI_Session compatibility method
  675. *
  676. * @param mixed $data Session data key or an associative array
  677. * @param mixed $value Value to store
  678. * @return void
  679. */
  680. public function set_userdata($data, $value = NULL)
  681. {
  682. if (is_array($data))
  683. {
  684. foreach ($data as $key => &$value)
  685. {
  686. $_SESSION[$key] = $value;
  687. }
  688. return;
  689. }
  690. $_SESSION[$data] = $value;
  691. }
  692. // ------------------------------------------------------------------------
  693. /**
  694. * Unset userdata
  695. *
  696. * Legacy CI_Session compatibility method
  697. *
  698. * @param mixed $key Session data key(s)
  699. * @return void
  700. */
  701. public function unset_userdata($key)
  702. {
  703. if (is_array($key))
  704. {
  705. foreach ($key as $k)
  706. {
  707. unset($_SESSION[$k]);
  708. }
  709. return;
  710. }
  711. unset($_SESSION[$key]);
  712. }
  713. // ------------------------------------------------------------------------
  714. /**
  715. * All userdata (fetch)
  716. *
  717. * Legacy CI_Session compatibility method
  718. *
  719. * @return array $_SESSION, excluding flash data items
  720. */
  721. public function all_userdata()
  722. {
  723. return $this->userdata();
  724. }
  725. // ------------------------------------------------------------------------
  726. /**
  727. * Has userdata
  728. *
  729. * Legacy CI_Session compatibility method
  730. *
  731. * @param string $key Session data key
  732. * @return bool
  733. */
  734. public function has_userdata($key)
  735. {
  736. return isset($_SESSION[$key]);
  737. }
  738. // ------------------------------------------------------------------------
  739. /**
  740. * Flashdata (fetch)
  741. *
  742. * Legacy CI_Session compatibility method
  743. *
  744. * @param string $key Session data key
  745. * @return mixed Session data value or NULL if not found
  746. */
  747. public function flashdata($key = NULL)
  748. {
  749. if (isset($key))
  750. {
  751. return (isset($_SESSION['__ci_vars'], $_SESSION['__ci_vars'][$key], $_SESSION[$key]) && ! is_int($_SESSION['__ci_vars'][$key]))
  752. ? $_SESSION[$key]
  753. : NULL;
  754. }
  755. $flashdata = array();
  756. if ( ! empty($_SESSION['__ci_vars']))
  757. {
  758. foreach ($_SESSION['__ci_vars'] as $key => &$value)
  759. {
  760. is_int($value) OR $flashdata[$key] = $_SESSION[$key];
  761. }
  762. }
  763. return $flashdata;
  764. }
  765. // ------------------------------------------------------------------------
  766. /**
  767. * Set flashdata
  768. *
  769. * Legacy CI_Session compatibility method
  770. *
  771. * @param mixed $data Session data key or an associative array
  772. * @param mixed $value Value to store
  773. * @return void
  774. */
  775. public function set_flashdata($data, $value = NULL)
  776. {
  777. $this->set_userdata($data, $value);
  778. $this->mark_as_flash(is_array($data) ? array_keys($data) : $data);
  779. }
  780. // ------------------------------------------------------------------------
  781. /**
  782. * Keep flashdata
  783. *
  784. * Legacy CI_Session compatibility method
  785. *
  786. * @param mixed $key Session data key(s)
  787. * @return void
  788. */
  789. public function keep_flashdata($key)
  790. {
  791. $this->mark_as_flash($key);
  792. }
  793. // ------------------------------------------------------------------------
  794. /**
  795. * Temp data (fetch)
  796. *
  797. * Legacy CI_Session compatibility method
  798. *
  799. * @param string $key Session data key
  800. * @return mixed Session data value or NULL if not found
  801. */
  802. public function tempdata($key = NULL)
  803. {
  804. if (isset($key))
  805. {
  806. return (isset($_SESSION['__ci_vars'], $_SESSION['__ci_vars'][$key], $_SESSION[$key]) && is_int($_SESSION['__ci_vars'][$key]))
  807. ? $_SESSION[$key]
  808. : NULL;
  809. }
  810. $tempdata = array();
  811. if ( ! empty($_SESSION['__ci_vars']))
  812. {
  813. foreach ($_SESSION['__ci_vars'] as $key => &$value)
  814. {
  815. is_int($value) && $tempdata[$key] = $_SESSION[$key];
  816. }
  817. }
  818. return $tempdata;
  819. }
  820. // ------------------------------------------------------------------------
  821. /**
  822. * Set tempdata
  823. *
  824. * Legacy CI_Session compatibility method
  825. *
  826. * @param mixed $data Session data key or an associative array of items
  827. * @param mixed $value Value to store
  828. * @param int $ttl Time-to-live in seconds
  829. * @return void
  830. */
  831. public function set_tempdata($data, $value = NULL, $ttl = 300)
  832. {
  833. $this->set_userdata($data, $value);
  834. $this->mark_as_temp(is_array($data) ? array_keys($data) : $data, $ttl);
  835. }
  836. // ------------------------------------------------------------------------
  837. /**
  838. * Unset tempdata
  839. *
  840. * Legacy CI_Session compatibility method
  841. *
  842. * @param mixed $data Session data key(s)
  843. * @return void
  844. */
  845. public function unset_tempdata($key)
  846. {
  847. $this->unmark_temp($key);
  848. }
  849. }