13 * obtain it through the world-wide-web, please send an email |
13 * obtain it through the world-wide-web, please send an email |
14 * to license@zend.com so we can send you a copy immediately. |
14 * to license@zend.com so we can send you a copy immediately. |
15 * |
15 * |
16 * @category Zend |
16 * @category Zend |
17 * @package Zend_Session |
17 * @package Zend_Session |
18 * @copyright Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com) |
18 * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com) |
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
19 * @license http://framework.zend.com/license/new-bsd New BSD License |
20 * @version $Id: Session.php 22587 2010-07-16 20:14:18Z ralph $ |
20 * @version $Id: Session.php 25121 2012-11-13 21:51:23Z matthew $ |
21 * @since Preview Release 0.2 |
21 * @since Preview Release 0.2 |
22 */ |
22 */ |
23 |
23 |
24 |
24 |
25 /** |
25 /** |
306 require_once 'Zend/Session/Exception.php'; |
306 require_once 'Zend/Session/Exception.php'; |
307 throw new Zend_Session_Exception("You must call " . __CLASS__ . '::' . __FUNCTION__ . |
307 throw new Zend_Session_Exception("You must call " . __CLASS__ . '::' . __FUNCTION__ . |
308 "() before any output has been sent to the browser; output started in {$filename}/{$linenum}"); |
308 "() before any output has been sent to the browser; output started in {$filename}/{$linenum}"); |
309 } |
309 } |
310 |
310 |
311 if (self::$_sessionStarted && self::$_regenerateIdState <= 0) { |
311 if ( !self::$_sessionStarted ) { |
|
312 self::$_regenerateIdState = -1; |
|
313 } else { |
312 if (!self::$_unitTestEnabled) { |
314 if (!self::$_unitTestEnabled) { |
313 session_regenerate_id(true); |
315 session_regenerate_id(true); |
314 } |
316 } |
315 self::$_regenerateIdState = 1; |
317 self::$_regenerateIdState = 1; |
316 } else { |
|
317 /** |
|
318 * @todo If we can detect that this requester had no session previously, |
|
319 * then why regenerate the id before the session has started? |
|
320 * Feedback wanted for: |
|
321 // |
|
322 if (isset($_COOKIE[session_name()]) || (!use only cookies && isset($_REQUEST[session_name()]))) { |
|
323 self::$_regenerateIdState = 1; |
|
324 } else { |
|
325 self::$_regenerateIdState = -1; |
|
326 } |
|
327 //*/ |
|
328 self::$_regenerateIdState = -1; |
|
329 } |
318 } |
330 } |
319 } |
331 |
320 |
332 |
321 |
333 /** |
322 /** |
334 * rememberMe() - Write a persistent cookie that expires after a number of seconds in the future. If no number of |
323 * rememberMe() - Write a persistent cookie that expires after a number of seconds in the future. If no number of |
335 * seconds is specified, then this defaults to self::$_rememberMeSeconds. Due to clock errors on end users' systems, |
324 * seconds is specified, then this defaults to self::$_rememberMeSeconds. Due to clock errors on end users' systems, |
336 * large values are recommended to avoid undesirable expiration of session cookies. |
325 * large values are recommended to avoid undesirable expiration of session cookies. |
337 * |
326 * |
338 * @param $seconds integer - OPTIONAL specifies TTL for cookie in seconds from present time |
327 * @param int $seconds OPTIONAL specifies TTL for cookie in seconds from present time |
339 * @return void |
328 * @return void |
340 */ |
329 */ |
341 public static function rememberMe($seconds = null) |
330 public static function rememberMe($seconds = null) |
342 { |
331 { |
343 $seconds = (int) $seconds; |
332 $seconds = (int) $seconds; |
424 * @throws Zend_Session_Exception |
413 * @throws Zend_Session_Exception |
425 * @return void |
414 * @return void |
426 */ |
415 */ |
427 public static function start($options = false) |
416 public static function start($options = false) |
428 { |
417 { |
|
418 // Check to see if we've been passed an invalid session ID |
|
419 if ( self::getId() && !self::_checkId(self::getId()) ) { |
|
420 // Generate a valid, temporary replacement |
|
421 self::setId(md5(self::getId())); |
|
422 // Force a regenerate after session is started |
|
423 self::$_regenerateIdState = -1; |
|
424 } |
|
425 |
429 if (self::$_sessionStarted && self::$_destroyed) { |
426 if (self::$_sessionStarted && self::$_destroyed) { |
430 require_once 'Zend/Session/Exception.php'; |
427 require_once 'Zend/Session/Exception.php'; |
431 throw new Zend_Session_Exception('The session was explicitly destroyed during this request, attempting to re-start is not allowed.'); |
428 throw new Zend_Session_Exception('The session was explicitly destroyed during this request, attempting to re-start is not allowed.'); |
432 } |
429 } |
433 |
430 |
506 if (isset($_SESSION['__ZF']['VALID'])) { |
503 if (isset($_SESSION['__ZF']['VALID'])) { |
507 self::_processValidators(); |
504 self::_processValidators(); |
508 } |
505 } |
509 |
506 |
510 self::_processStartupMetadataGlobal(); |
507 self::_processStartupMetadataGlobal(); |
|
508 } |
|
509 |
|
510 /** |
|
511 * Perform a hash-bits check on the session ID |
|
512 * |
|
513 * @param string $id Session ID |
|
514 * @return bool |
|
515 */ |
|
516 protected static function _checkId($id) |
|
517 { |
|
518 $saveHandler = ini_get('session.save_handler'); |
|
519 if ($saveHandler == 'cluster') { // Zend Server SC, validate only after last dash |
|
520 $dashPos = strrpos($id, '-'); |
|
521 if ($dashPos) { |
|
522 $id = substr($id, $dashPos + 1); |
|
523 } |
|
524 } |
|
525 |
|
526 $hashBitsPerChar = ini_get('session.hash_bits_per_character'); |
|
527 if (!$hashBitsPerChar) { |
|
528 $hashBitsPerChar = 5; // the default value |
|
529 } |
|
530 switch($hashBitsPerChar) { |
|
531 case 4: $pattern = '^[0-9a-f]*$'; break; |
|
532 case 5: $pattern = '^[0-9a-v]*$'; break; |
|
533 case 6: $pattern = '^[0-9a-zA-Z-,]*$'; break; |
|
534 } |
|
535 return preg_match('#'.$pattern.'#', $id); |
511 } |
536 } |
512 |
537 |
513 |
538 |
514 /** |
539 /** |
515 * _processGlobalMetadata() - this method initizes the sessions GLOBAL |
540 * _processGlobalMetadata() - this method initizes the sessions GLOBAL |
570 } |
595 } |
571 unset($_SESSION['__ZF'][$namespace]['ENVGH'][$variable]); |
596 unset($_SESSION['__ZF'][$namespace]['ENVGH'][$variable]); |
572 } |
597 } |
573 } |
598 } |
574 if (empty($_SESSION['__ZF'][$namespace]['ENVGH'])) { |
599 if (empty($_SESSION['__ZF'][$namespace]['ENVGH'])) { |
575 unset($_SESSION['__ZF'][$namespace]['ENVGH']); |
600 unset($_SESSION['__ZF'][$namespace]['ENVGH']); |
576 } |
601 } |
577 } |
602 } |
578 } |
603 |
579 |
604 if (isset($namespace) && empty($_SESSION['__ZF'][$namespace])) { |
580 if (isset($namespace) && empty($_SESSION['__ZF'][$namespace])) { |
605 unset($_SESSION['__ZF'][$namespace]); |
581 unset($_SESSION['__ZF'][$namespace]); |
606 } |
582 } |
607 } |
583 } |
608 } |
584 |
609 |
585 if (isset($_SESSION['__ZF']) && empty($_SESSION['__ZF'])) { |
610 if (isset($_SESSION['__ZF']) && empty($_SESSION['__ZF'])) { |
586 unset($_SESSION['__ZF']); |
611 unset($_SESSION['__ZF']); |