File indexing completed on 2024-12-22 05:37:18
0001 <?php 0002 0003 /** 0004 * Zend Framework 0005 * 0006 * LICENSE 0007 * 0008 * This source file is subject to the new BSD license that is bundled 0009 * with this package in the file LICENSE.txt. 0010 * It is also available through the world-wide-web at this URL: 0011 * http://framework.zend.com/license/new-bsd 0012 * If you did not receive a copy of the license and are unable to 0013 * obtain it through the world-wide-web, please send an email 0014 * to license@zend.com so we can send you a copy immediately. 0015 * 0016 * @category Zend 0017 * @package Zend_Session 0018 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0019 * @license http://framework.zend.com/license/new-bsd New BSD License 0020 * @version $Id$ 0021 * @since Preview Release 0.2 0022 */ 0023 0024 0025 /** 0026 * @see Zend_Session_Abstract 0027 */ 0028 // require_once 'Zend/Session/Abstract.php'; 0029 0030 /** 0031 * @see Zend_Session_Namespace 0032 */ 0033 // require_once 'Zend/Session/Namespace.php'; 0034 0035 /** 0036 * @see Zend_Session_SaveHandler_Interface 0037 */ 0038 // require_once 'Zend/Session/SaveHandler/Interface.php'; 0039 0040 0041 /** 0042 * Zend_Session 0043 * 0044 * @category Zend 0045 * @package Zend_Session 0046 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0047 * @license http://framework.zend.com/license/new-bsd New BSD License 0048 */ 0049 class Zend_Session extends Zend_Session_Abstract 0050 { 0051 /** 0052 * Whether or not Zend_Session is being used with unit tests 0053 * 0054 * @internal 0055 * @var bool 0056 */ 0057 public static $_unitTestEnabled = false; 0058 0059 /** 0060 * $_throwStartupException 0061 * 0062 * @var bool|bitset This could also be a combiniation of error codes to catch 0063 */ 0064 protected static $_throwStartupExceptions = true; 0065 0066 /** 0067 * Check whether or not the session was started 0068 * 0069 * @var bool 0070 */ 0071 private static $_sessionStarted = false; 0072 0073 /** 0074 * Whether or not the session id has been regenerated this request. 0075 * 0076 * Id regeneration state 0077 * <0 - regenerate requested when session is started 0078 * 0 - do nothing 0079 * >0 - already called session_regenerate_id() 0080 * 0081 * @var int 0082 */ 0083 private static $_regenerateIdState = 0; 0084 0085 /** 0086 * Private list of php's ini values for ext/session 0087 * null values will default to the php.ini value, otherwise 0088 * the value below will overwrite the default ini value, unless 0089 * the user has set an option explicity with setOptions() 0090 * 0091 * @var array 0092 */ 0093 private static $_defaultOptions = array( 0094 'save_path' => null, 0095 'name' => null, /* this should be set to a unique value for each application */ 0096 'save_handler' => null, 0097 //'auto_start' => null, /* intentionally excluded (see manual) */ 0098 'gc_probability' => null, 0099 'gc_divisor' => null, 0100 'gc_maxlifetime' => null, 0101 'serialize_handler' => null, 0102 'cookie_lifetime' => null, 0103 'cookie_path' => null, 0104 'cookie_domain' => null, 0105 'cookie_secure' => null, 0106 'cookie_httponly' => null, 0107 'use_cookies' => null, 0108 'use_only_cookies' => 'on', 0109 'referer_check' => null, 0110 'entropy_file' => null, 0111 'entropy_length' => null, 0112 'cache_limiter' => null, 0113 'cache_expire' => null, 0114 'use_trans_sid' => null, 0115 'bug_compat_42' => null, 0116 'bug_compat_warn' => null, 0117 'hash_function' => null, 0118 'hash_bits_per_character' => null 0119 ); 0120 0121 /** 0122 * List of options pertaining to Zend_Session that can be set by developers 0123 * using Zend_Session::setOptions(). This list intentionally duplicates 0124 * the individual declaration of static "class" variables by the same names. 0125 * 0126 * @var array 0127 */ 0128 private static $_localOptions = array( 0129 'strict' => '_strict', 0130 'remember_me_seconds' => '_rememberMeSeconds', 0131 'throw_startup_exceptions' => '_throwStartupExceptions' 0132 ); 0133 0134 /** 0135 * Whether or not write close has been performed. 0136 * 0137 * @var bool 0138 */ 0139 private static $_writeClosed = false; 0140 0141 /** 0142 * Whether or not session id cookie has been deleted 0143 * 0144 * @var bool 0145 */ 0146 private static $_sessionCookieDeleted = false; 0147 0148 /** 0149 * Whether or not session has been destroyed via session_destroy() 0150 * 0151 * @var bool 0152 */ 0153 private static $_destroyed = false; 0154 0155 /** 0156 * Whether or not session must be initiated before usage 0157 * 0158 * @var bool 0159 */ 0160 private static $_strict = false; 0161 0162 /** 0163 * Default number of seconds the session will be remembered for when asked to be remembered 0164 * 0165 * @var int 0166 */ 0167 private static $_rememberMeSeconds = 1209600; // 2 weeks 0168 0169 /** 0170 * Whether the default options listed in Zend_Session::$_localOptions have been set 0171 * 0172 * @var bool 0173 */ 0174 private static $_defaultOptionsSet = false; 0175 0176 /** 0177 * A reference to the set session save handler 0178 * 0179 * @var Zend_Session_SaveHandler_Interface 0180 */ 0181 private static $_saveHandler = null; 0182 0183 0184 /** 0185 * Constructor overriding - make sure that a developer cannot instantiate 0186 */ 0187 protected function __construct() 0188 { 0189 } 0190 0191 0192 /** 0193 * setOptions - set both the class specified 0194 * 0195 * @param array $userOptions - pass-by-keyword style array of <option name, option value> pairs 0196 * @throws Zend_Session_Exception 0197 * @return void 0198 */ 0199 public static function setOptions(array $userOptions = array()) 0200 { 0201 // set default options on first run only (before applying user settings) 0202 if (!self::$_defaultOptionsSet) { 0203 foreach (self::$_defaultOptions as $defaultOptionName => $defaultOptionValue) { 0204 if (isset(self::$_defaultOptions[$defaultOptionName])) { 0205 ini_set("session.$defaultOptionName", $defaultOptionValue); 0206 } 0207 } 0208 0209 self::$_defaultOptionsSet = true; 0210 } 0211 0212 // set the options the user has requested to set 0213 foreach ($userOptions as $userOptionName => $userOptionValue) { 0214 0215 $userOptionName = strtolower($userOptionName); 0216 0217 // set the ini based values 0218 if (array_key_exists($userOptionName, self::$_defaultOptions)) { 0219 ini_set("session.$userOptionName", $userOptionValue); 0220 } 0221 elseif (isset(self::$_localOptions[$userOptionName])) { 0222 self::${self::$_localOptions[$userOptionName]} = $userOptionValue; 0223 } 0224 else { 0225 /** @see Zend_Session_Exception */ 0226 // require_once 'Zend/Session/Exception.php'; 0227 throw new Zend_Session_Exception("Unknown option: $userOptionName = $userOptionValue"); 0228 } 0229 } 0230 } 0231 0232 /** 0233 * getOptions() 0234 * 0235 * @param string $optionName OPTIONAL 0236 * @return array|string 0237 */ 0238 public static function getOptions($optionName = null) 0239 { 0240 $options = array(); 0241 foreach (ini_get_all('session') as $sysOptionName => $sysOptionValues) { 0242 $options[substr($sysOptionName, 8)] = $sysOptionValues['local_value']; 0243 } 0244 foreach (self::$_localOptions as $localOptionName => $localOptionMemberName) { 0245 $options[$localOptionName] = self::${$localOptionMemberName}; 0246 } 0247 0248 if ($optionName) { 0249 if (array_key_exists($optionName, $options)) { 0250 return $options[$optionName]; 0251 } 0252 return null; 0253 } 0254 0255 return $options; 0256 } 0257 0258 /** 0259 * setSaveHandler() - Session Save Handler assignment 0260 * 0261 * @param Zend_Session_SaveHandler_Interface $interface 0262 * @throws Zend_Session_Exception When the session_set_save_handler call fails 0263 * @return void 0264 */ 0265 public static function setSaveHandler(Zend_Session_SaveHandler_Interface $saveHandler) 0266 { 0267 self::$_saveHandler = $saveHandler; 0268 0269 if (self::$_unitTestEnabled) { 0270 return; 0271 } 0272 0273 $result = session_set_save_handler( 0274 array(&$saveHandler, 'open'), 0275 array(&$saveHandler, 'close'), 0276 array(&$saveHandler, 'read'), 0277 array(&$saveHandler, 'write'), 0278 array(&$saveHandler, 'destroy'), 0279 array(&$saveHandler, 'gc') 0280 ); 0281 0282 if (!$result) { 0283 throw new Zend_Session_Exception('Unable to set session handler'); 0284 } 0285 } 0286 0287 0288 /** 0289 * getSaveHandler() - Get the session Save Handler 0290 * 0291 * @return Zend_Session_SaveHandler_Interface 0292 */ 0293 public static function getSaveHandler() 0294 { 0295 return self::$_saveHandler; 0296 } 0297 0298 0299 /** 0300 * regenerateId() - Regenerate the session id. Best practice is to call this after 0301 * session is started. If called prior to session starting, session id will be regenerated 0302 * at start time. 0303 * 0304 * @throws Zend_Session_Exception 0305 * @return void 0306 */ 0307 public static function regenerateId() 0308 { 0309 if (!self::$_unitTestEnabled && headers_sent($filename, $linenum)) { 0310 /** @see Zend_Session_Exception */ 0311 // require_once 'Zend/Session/Exception.php'; 0312 throw new Zend_Session_Exception("You must call " . __CLASS__ . '::' . __FUNCTION__ . 0313 "() before any output has been sent to the browser; output started in {$filename}/{$linenum}"); 0314 } 0315 0316 if ( !self::$_sessionStarted ) { 0317 self::$_regenerateIdState = -1; 0318 } else { 0319 if (!self::$_unitTestEnabled) { 0320 session_regenerate_id(true); 0321 } 0322 self::$_regenerateIdState = 1; 0323 } 0324 } 0325 0326 0327 /** 0328 * rememberMe() - Write a persistent cookie that expires after a number of seconds in the future. If no number of 0329 * seconds is specified, then this defaults to self::$_rememberMeSeconds. Due to clock errors on end users' systems, 0330 * large values are recommended to avoid undesirable expiration of session cookies. 0331 * 0332 * @param int $seconds OPTIONAL specifies TTL for cookie in seconds from present time 0333 * @return void 0334 */ 0335 public static function rememberMe($seconds = null) 0336 { 0337 $seconds = (int) $seconds; 0338 $seconds = ($seconds > 0) ? $seconds : self::$_rememberMeSeconds; 0339 0340 self::rememberUntil($seconds); 0341 } 0342 0343 0344 /** 0345 * forgetMe() - Write a volatile session cookie, removing any persistent cookie that may have existed. The session 0346 * would end upon, for example, termination of a web browser program. 0347 * 0348 * @return void 0349 */ 0350 public static function forgetMe() 0351 { 0352 self::rememberUntil(0); 0353 } 0354 0355 0356 /** 0357 * rememberUntil() - This method does the work of changing the state of the session cookie and making 0358 * sure that it gets resent to the browser via regenerateId() 0359 * 0360 * @param int $seconds 0361 * @return void 0362 */ 0363 public static function rememberUntil($seconds = 0) 0364 { 0365 if (self::$_unitTestEnabled) { 0366 self::regenerateId(); 0367 return; 0368 } 0369 0370 $cookieParams = session_get_cookie_params(); 0371 0372 session_set_cookie_params( 0373 $seconds, 0374 $cookieParams['path'], 0375 $cookieParams['domain'], 0376 $cookieParams['secure'] 0377 ); 0378 0379 // normally "rememberMe()" represents a security context change, so should use new session id 0380 self::regenerateId(); 0381 } 0382 0383 0384 /** 0385 * sessionExists() - whether or not a session exists for the current request 0386 * 0387 * @return bool 0388 */ 0389 public static function sessionExists() 0390 { 0391 if ((bool)ini_get('session.use_cookies') == true && isset($_COOKIE[session_name()])) { 0392 return true; 0393 } elseif ((bool)ini_get('session.use_only_cookies') == false && isset($_REQUEST[session_name()])) { 0394 return true; 0395 } elseif (self::$_unitTestEnabled) { 0396 return true; 0397 } 0398 0399 return false; 0400 } 0401 0402 0403 /** 0404 * Whether or not session has been destroyed via session_destroy() 0405 * 0406 * @return bool 0407 */ 0408 public static function isDestroyed() 0409 { 0410 return self::$_destroyed; 0411 } 0412 0413 0414 /** 0415 * start() - Start the session. 0416 * 0417 * @param bool|array $options OPTIONAL Either user supplied options, or flag indicating if start initiated automatically 0418 * @throws Zend_Session_Exception 0419 * @return void 0420 */ 0421 public static function start($options = false) 0422 { 0423 // Check to see if we've been passed an invalid session ID 0424 if ( self::getId() && !self::_checkId(self::getId()) ) { 0425 // Generate a valid, temporary replacement 0426 self::setId(md5(self::getId())); 0427 // Force a regenerate after session is started 0428 self::$_regenerateIdState = -1; 0429 } 0430 0431 if (self::$_sessionStarted && self::$_destroyed) { 0432 // require_once 'Zend/Session/Exception.php'; 0433 throw new Zend_Session_Exception('The session was explicitly destroyed during this request, attempting to re-start is not allowed.'); 0434 } 0435 0436 if (self::$_sessionStarted) { 0437 return; // already started 0438 } 0439 0440 // make sure our default options (at the least) have been set 0441 if (!self::$_defaultOptionsSet) { 0442 self::setOptions(is_array($options) ? $options : array()); 0443 } 0444 0445 // In strict mode, do not allow auto-starting Zend_Session, such as via "new Zend_Session_Namespace()" 0446 if (self::$_strict && $options === true) { 0447 /** @see Zend_Session_Exception */ 0448 // require_once 'Zend/Session/Exception.php'; 0449 throw new Zend_Session_Exception('You must explicitly start the session with Zend_Session::start() when session options are set to strict.'); 0450 } 0451 0452 $filename = $linenum = null; 0453 if (!self::$_unitTestEnabled && headers_sent($filename, $linenum)) { 0454 /** @see Zend_Session_Exception */ 0455 // require_once 'Zend/Session/Exception.php'; 0456 throw new Zend_Session_Exception("Session must be started before any output has been sent to the browser;" 0457 . " output started in {$filename}/{$linenum}"); 0458 } 0459 0460 // See http://www.php.net/manual/en/ref.session.php for explanation 0461 if (!self::$_unitTestEnabled && defined('SID')) { 0462 /** @see Zend_Session_Exception */ 0463 // require_once 'Zend/Session/Exception.php'; 0464 throw new Zend_Session_Exception('session has already been started by session.auto-start or session_start()'); 0465 } 0466 0467 /** 0468 * Hack to throw exceptions on start instead of php errors 0469 * @see http://framework.zend.com/issues/browse/ZF-1325 0470 */ 0471 0472 $errorLevel = (is_int(self::$_throwStartupExceptions)) ? self::$_throwStartupExceptions : E_ALL; 0473 0474 /** @see Zend_Session_Exception */ 0475 if (!self::$_unitTestEnabled) { 0476 0477 if (self::$_throwStartupExceptions) { 0478 // require_once 'Zend/Session/Exception.php'; 0479 set_error_handler(array('Zend_Session_Exception', 'handleSessionStartError'), $errorLevel); 0480 } 0481 0482 $startedCleanly = session_start(); 0483 0484 if (self::$_throwStartupExceptions) { 0485 restore_error_handler(); 0486 } 0487 0488 if (!$startedCleanly || Zend_Session_Exception::$sessionStartError != null) { 0489 if (self::$_throwStartupExceptions) { 0490 set_error_handler(array('Zend_Session_Exception', 'handleSilentWriteClose'), $errorLevel); 0491 } 0492 session_write_close(); 0493 if (self::$_throwStartupExceptions) { 0494 restore_error_handler(); 0495 throw new Zend_Session_Exception(__CLASS__ . '::' . __FUNCTION__ . '() - ' . Zend_Session_Exception::$sessionStartError); 0496 } 0497 } 0498 } 0499 0500 parent::$_readable = true; 0501 parent::$_writable = true; 0502 self::$_sessionStarted = true; 0503 if (self::$_regenerateIdState === -1) { 0504 self::regenerateId(); 0505 } 0506 0507 // run validators if they exist 0508 if (isset($_SESSION['__ZF']['VALID'])) { 0509 self::_processValidators(); 0510 } 0511 0512 self::_processStartupMetadataGlobal(); 0513 } 0514 0515 /** 0516 * Perform a hash-bits check on the session ID 0517 * 0518 * @param string $id Session ID 0519 * @return bool 0520 */ 0521 protected static function _checkId($id) 0522 { 0523 $saveHandler = ini_get('session.save_handler'); 0524 if ($saveHandler == 'cluster') { // Zend Server SC, validate only after last dash 0525 $dashPos = strrpos($id, '-'); 0526 if ($dashPos) { 0527 $id = substr($id, $dashPos + 1); 0528 } 0529 } 0530 0531 $hashBitsPerChar = ini_get('session.hash_bits_per_character'); 0532 if (!$hashBitsPerChar) { 0533 $hashBitsPerChar = 5; // the default value 0534 } 0535 switch($hashBitsPerChar) { 0536 case 4: $pattern = '^[0-9a-f]*$'; break; 0537 case 5: $pattern = '^[0-9a-v]*$'; break; 0538 case 6: $pattern = '^[0-9a-zA-Z-,]*$'; break; 0539 } 0540 return preg_match('#'.$pattern.'#', $id); 0541 } 0542 0543 0544 /** 0545 * _processGlobalMetadata() - this method initizes the sessions GLOBAL 0546 * metadata, mostly global data expiration calculations. 0547 * 0548 * @return void 0549 */ 0550 private static function _processStartupMetadataGlobal() 0551 { 0552 // process global metadata 0553 if (isset($_SESSION['__ZF'])) { 0554 0555 // expire globally expired values 0556 foreach ($_SESSION['__ZF'] as $namespace => $namespace_metadata) { 0557 0558 // Expire Namespace by Time (ENT) 0559 if (isset($namespace_metadata['ENT']) && ($namespace_metadata['ENT'] > 0) && (time() > $namespace_metadata['ENT']) ) { 0560 unset($_SESSION[$namespace]); 0561 unset($_SESSION['__ZF'][$namespace]); 0562 } 0563 0564 // Expire Namespace by Global Hop (ENGH) if it wasnt expired above 0565 if (isset($_SESSION['__ZF'][$namespace]) && isset($namespace_metadata['ENGH']) && $namespace_metadata['ENGH'] >= 1) { 0566 0567 $_SESSION['__ZF'][$namespace]['ENGH']--; 0568 0569 if ($_SESSION['__ZF'][$namespace]['ENGH'] === 0) { 0570 if (isset($_SESSION[$namespace])) { 0571 parent::$_expiringData[$namespace] = $_SESSION[$namespace]; 0572 unset($_SESSION[$namespace]); 0573 } 0574 unset($_SESSION['__ZF'][$namespace]); 0575 } 0576 } 0577 0578 // Expire Namespace Variables by Time (ENVT) 0579 if (isset($namespace_metadata['ENVT'])) { 0580 foreach ($namespace_metadata['ENVT'] as $variable => $time) { 0581 if (time() > $time) { 0582 unset($_SESSION[$namespace][$variable]); 0583 unset($_SESSION['__ZF'][$namespace]['ENVT'][$variable]); 0584 } 0585 } 0586 if (empty($_SESSION['__ZF'][$namespace]['ENVT'])) { 0587 unset($_SESSION['__ZF'][$namespace]['ENVT']); 0588 } 0589 } 0590 0591 // Expire Namespace Variables by Global Hop (ENVGH) 0592 if (isset($namespace_metadata['ENVGH'])) { 0593 foreach ($namespace_metadata['ENVGH'] as $variable => $hops) { 0594 $_SESSION['__ZF'][$namespace]['ENVGH'][$variable]--; 0595 0596 if ($_SESSION['__ZF'][$namespace]['ENVGH'][$variable] === 0) { 0597 if (isset($_SESSION[$namespace][$variable])) { 0598 parent::$_expiringData[$namespace][$variable] = $_SESSION[$namespace][$variable]; 0599 unset($_SESSION[$namespace][$variable]); 0600 } 0601 unset($_SESSION['__ZF'][$namespace]['ENVGH'][$variable]); 0602 } 0603 } 0604 if (empty($_SESSION['__ZF'][$namespace]['ENVGH'])) { 0605 unset($_SESSION['__ZF'][$namespace]['ENVGH']); 0606 } 0607 } 0608 0609 if (isset($namespace) && empty($_SESSION['__ZF'][$namespace])) { 0610 unset($_SESSION['__ZF'][$namespace]); 0611 } 0612 } 0613 } 0614 0615 if (isset($_SESSION['__ZF']) && empty($_SESSION['__ZF'])) { 0616 unset($_SESSION['__ZF']); 0617 } 0618 } 0619 0620 0621 /** 0622 * isStarted() - convenience method to determine if the session is already started. 0623 * 0624 * @return bool 0625 */ 0626 public static function isStarted() 0627 { 0628 return self::$_sessionStarted; 0629 } 0630 0631 0632 /** 0633 * isRegenerated() - convenience method to determine if session_regenerate_id() 0634 * has been called during this request by Zend_Session. 0635 * 0636 * @return bool 0637 */ 0638 public static function isRegenerated() 0639 { 0640 return ( (self::$_regenerateIdState > 0) ? true : false ); 0641 } 0642 0643 0644 /** 0645 * getId() - get the current session id 0646 * 0647 * @return string 0648 */ 0649 public static function getId() 0650 { 0651 return session_id(); 0652 } 0653 0654 0655 /** 0656 * setId() - set an id to a user specified id 0657 * 0658 * @throws Zend_Session_Exception 0659 * @param string $id 0660 * @return void 0661 */ 0662 public static function setId($id) 0663 { 0664 if (!self::$_unitTestEnabled && defined('SID')) { 0665 /** @see Zend_Session_Exception */ 0666 // require_once 'Zend/Session/Exception.php'; 0667 throw new Zend_Session_Exception('The session has already been started. The session id must be set first.'); 0668 } 0669 0670 if (!self::$_unitTestEnabled && headers_sent($filename, $linenum)) { 0671 /** @see Zend_Session_Exception */ 0672 // require_once 'Zend/Session/Exception.php'; 0673 throw new Zend_Session_Exception("You must call ".__CLASS__.'::'.__FUNCTION__. 0674 "() before any output has been sent to the browser; output started in {$filename}/{$linenum}"); 0675 } 0676 0677 if (!is_string($id) || $id === '') { 0678 /** @see Zend_Session_Exception */ 0679 // require_once 'Zend/Session/Exception.php'; 0680 throw new Zend_Session_Exception('You must provide a non-empty string as a session identifier.'); 0681 } 0682 0683 session_id($id); 0684 } 0685 0686 0687 /** 0688 * registerValidator() - register a validator that will attempt to validate this session for 0689 * every future request 0690 * 0691 * @param Zend_Session_Validator_Interface $validator 0692 * @return void 0693 */ 0694 public static function registerValidator(Zend_Session_Validator_Interface $validator) 0695 { 0696 $validator->setup(); 0697 } 0698 0699 0700 /** 0701 * stop() - Disable write access. Optionally disable read (not implemented). 0702 * 0703 * @return void 0704 */ 0705 public static function stop() 0706 { 0707 parent::$_writable = false; 0708 } 0709 0710 0711 /** 0712 * writeClose() - Shutdown the sesssion, close writing and detach $_SESSION from the back-end storage mechanism. 0713 * This will complete the internal data transformation on this request. 0714 * 0715 * @param bool $readonly - OPTIONAL remove write access (i.e. throw error if Zend_Session's attempt writes) 0716 * @return void 0717 */ 0718 public static function writeClose($readonly = true) 0719 { 0720 if (self::$_unitTestEnabled) { 0721 return; 0722 } 0723 0724 if (self::$_writeClosed) { 0725 return; 0726 } 0727 0728 if ($readonly) { 0729 parent::$_writable = false; 0730 } 0731 0732 session_write_close(); 0733 self::$_writeClosed = true; 0734 } 0735 0736 0737 /** 0738 * destroy() - This is used to destroy session data, and optionally, the session cookie itself 0739 * 0740 * @param bool $remove_cookie - OPTIONAL remove session id cookie, defaults to true (remove cookie) 0741 * @param bool $readonly - OPTIONAL remove write access (i.e. throw error if Zend_Session's attempt writes) 0742 * @return void 0743 */ 0744 public static function destroy($remove_cookie = true, $readonly = true) 0745 { 0746 if (self::$_unitTestEnabled) { 0747 return; 0748 } 0749 0750 if (self::$_destroyed) { 0751 return; 0752 } 0753 0754 if ($readonly) { 0755 parent::$_writable = false; 0756 } 0757 0758 session_destroy(); 0759 self::$_destroyed = true; 0760 0761 if ($remove_cookie) { 0762 self::expireSessionCookie(); 0763 } 0764 } 0765 0766 0767 /** 0768 * expireSessionCookie() - Sends an expired session id cookie, causing the client to delete the session cookie 0769 * 0770 * @return void 0771 */ 0772 public static function expireSessionCookie() 0773 { 0774 if (self::$_unitTestEnabled) { 0775 return; 0776 } 0777 0778 if (self::$_sessionCookieDeleted) { 0779 return; 0780 } 0781 0782 self::$_sessionCookieDeleted = true; 0783 0784 if (isset($_COOKIE[session_name()])) { 0785 $cookie_params = session_get_cookie_params(); 0786 0787 setcookie( 0788 session_name(), 0789 false, 0790 315554400, // strtotime('1980-01-01'), 0791 $cookie_params['path'], 0792 $cookie_params['domain'], 0793 $cookie_params['secure'] 0794 ); 0795 } 0796 } 0797 0798 0799 /** 0800 * _processValidator() - internal function that is called in the existence of VALID metadata 0801 * 0802 * @throws Zend_Session_Exception 0803 * @return void 0804 */ 0805 private static function _processValidators() 0806 { 0807 foreach ($_SESSION['__ZF']['VALID'] as $validator_name => $valid_data) { 0808 if (!class_exists($validator_name)) { 0809 // require_once 'Zend/Loader.php'; 0810 Zend_Loader::loadClass($validator_name); 0811 } 0812 $validator = new $validator_name; 0813 if ($validator->validate() === false) { 0814 /** @see Zend_Session_Validator_Exception */ 0815 // require_once 'Zend/Session/Validator/Exception.php'; 0816 throw new Zend_Session_Validator_Exception("This session is not valid according to {$validator_name}."); 0817 } 0818 } 0819 } 0820 0821 0822 /** 0823 * namespaceIsset() - check to see if a namespace is set 0824 * 0825 * @param string $namespace 0826 * @return bool 0827 */ 0828 public static function namespaceIsset($namespace) 0829 { 0830 return parent::_namespaceIsset($namespace); 0831 } 0832 0833 0834 /** 0835 * namespaceUnset() - unset a namespace or a variable within a namespace 0836 * 0837 * @param string $namespace 0838 * @throws Zend_Session_Exception 0839 * @return void 0840 */ 0841 public static function namespaceUnset($namespace) 0842 { 0843 parent::_namespaceUnset($namespace); 0844 Zend_Session_Namespace::resetSingleInstance($namespace); 0845 } 0846 0847 0848 /** 0849 * namespaceGet() - get all variables in a namespace 0850 * Deprecated: Use getIterator() in Zend_Session_Namespace. 0851 * 0852 * @param string $namespace 0853 * @return array 0854 */ 0855 public static function namespaceGet($namespace) 0856 { 0857 return parent::_namespaceGetAll($namespace); 0858 } 0859 0860 0861 /** 0862 * getIterator() - return an iteratable object for use in foreach and the like, 0863 * this completes the IteratorAggregate interface 0864 * 0865 * @throws Zend_Session_Exception 0866 * @return ArrayObject 0867 */ 0868 public static function getIterator() 0869 { 0870 if (parent::$_readable === false) { 0871 /** @see Zend_Session_Exception */ 0872 // require_once 'Zend/Session/Exception.php'; 0873 throw new Zend_Session_Exception(parent::_THROW_NOT_READABLE_MSG); 0874 } 0875 0876 $spaces = array(); 0877 if (isset($_SESSION)) { 0878 $spaces = array_keys($_SESSION); 0879 foreach($spaces as $key => $space) { 0880 if (!strncmp($space, '__', 2) || !is_array($_SESSION[$space])) { 0881 unset($spaces[$key]); 0882 } 0883 } 0884 } 0885 0886 return new ArrayObject(array_merge($spaces, array_keys(parent::$_expiringData))); 0887 } 0888 0889 0890 /** 0891 * isWritable() - returns a boolean indicating if namespaces can write (use setters) 0892 * 0893 * @return bool 0894 */ 0895 public static function isWritable() 0896 { 0897 return parent::$_writable; 0898 } 0899 0900 0901 /** 0902 * isReadable() - returns a boolean indicating if namespaces can write (use setters) 0903 * 0904 * @return bool 0905 */ 0906 public static function isReadable() 0907 { 0908 return parent::$_readable; 0909 } 0910 0911 }