[ Index ] |
PHP Cross Reference of phpBB-3.1.12-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12 namespace Symfony\Component\HttpFoundation\Session\Storage; 13 14 use Symfony\Component\HttpFoundation\Session\SessionBagInterface; 15 use Symfony\Component\HttpFoundation\Session\Storage\Handler\NativeSessionHandler; 16 use Symfony\Component\HttpFoundation\Session\Storage\Proxy\NativeProxy; 17 use Symfony\Component\HttpFoundation\Session\Storage\Proxy\AbstractProxy; 18 use Symfony\Component\HttpFoundation\Session\Storage\Proxy\SessionHandlerProxy; 19 20 /** 21 * This provides a base class for session attribute storage. 22 * 23 * @author Drak <drak@zikula.org> 24 */ 25 class NativeSessionStorage implements SessionStorageInterface 26 { 27 /** 28 * Array of SessionBagInterface. 29 * 30 * @var SessionBagInterface[] 31 */ 32 protected $bags; 33 34 /** 35 * @var bool 36 */ 37 protected $started = false; 38 39 /** 40 * @var bool 41 */ 42 protected $closed = false; 43 44 /** 45 * @var AbstractProxy 46 */ 47 protected $saveHandler; 48 49 /** 50 * @var MetadataBag 51 */ 52 protected $metadataBag; 53 54 /** 55 * Constructor. 56 * 57 * Depending on how you want the storage driver to behave you probably 58 * want to override this constructor entirely. 59 * 60 * List of options for $options array with their defaults. 61 * 62 * @see http://php.net/session.configuration for options 63 * but we omit 'session.' from the beginning of the keys for convenience. 64 * 65 * ("auto_start", is not supported as it tells PHP to start a session before 66 * PHP starts to execute user-land code. Setting during runtime has no effect). 67 * 68 * cache_limiter, "" (use "0" to prevent headers from being sent entirely). 69 * cookie_domain, "" 70 * cookie_httponly, "" 71 * cookie_lifetime, "0" 72 * cookie_path, "/" 73 * cookie_secure, "" 74 * entropy_file, "" 75 * entropy_length, "0" 76 * gc_divisor, "100" 77 * gc_maxlifetime, "1440" 78 * gc_probability, "1" 79 * hash_bits_per_character, "4" 80 * hash_function, "0" 81 * name, "PHPSESSID" 82 * referer_check, "" 83 * serialize_handler, "php" 84 * use_cookies, "1" 85 * use_only_cookies, "1" 86 * use_trans_sid, "0" 87 * upload_progress.enabled, "1" 88 * upload_progress.cleanup, "1" 89 * upload_progress.prefix, "upload_progress_" 90 * upload_progress.name, "PHP_SESSION_UPLOAD_PROGRESS" 91 * upload_progress.freq, "1%" 92 * upload_progress.min-freq, "1" 93 * url_rewriter.tags, "a=href,area=href,frame=src,form=,fieldset=" 94 * 95 * @param array $options Session configuration options. 96 * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $handler 97 * @param MetadataBag $metaBag MetadataBag. 98 */ 99 public function __construct(array $options = array(), $handler = null, MetadataBag $metaBag = null) 100 { 101 session_cache_limiter(''); // disable by default because it's managed by HeaderBag (if used) 102 ini_set('session.use_cookies', 1); 103 104 if (PHP_VERSION_ID >= 50400) { 105 session_register_shutdown(); 106 } else { 107 register_shutdown_function('session_write_close'); 108 } 109 110 $this->setMetadataBag($metaBag); 111 $this->setOptions($options); 112 $this->setSaveHandler($handler); 113 } 114 115 /** 116 * Gets the save handler instance. 117 * 118 * @return AbstractProxy 119 */ 120 public function getSaveHandler() 121 { 122 return $this->saveHandler; 123 } 124 125 /** 126 * {@inheritdoc} 127 */ 128 public function start() 129 { 130 if ($this->started) { 131 return true; 132 } 133 134 if (PHP_VERSION_ID >= 50400 && \PHP_SESSION_ACTIVE === session_status()) { 135 throw new \RuntimeException('Failed to start the session: already started by PHP.'); 136 } 137 138 if (PHP_VERSION_ID < 50400 && !$this->closed && isset($_SESSION) && session_id()) { 139 // not 100% fool-proof, but is the most reliable way to determine if a session is active in PHP 5.3 140 throw new \RuntimeException('Failed to start the session: already started by PHP ($_SESSION is set).'); 141 } 142 143 if (ini_get('session.use_cookies') && headers_sent($file, $line)) { 144 throw new \RuntimeException(sprintf('Failed to start the session because headers have already been sent by "%s" at line %d.', $file, $line)); 145 } 146 147 // ok to try and start the session 148 if (!session_start()) { 149 throw new \RuntimeException('Failed to start the session'); 150 } 151 152 $this->loadSession(); 153 if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) { 154 // This condition matches only PHP 5.3 with internal save handlers 155 $this->saveHandler->setActive(true); 156 } 157 158 return true; 159 } 160 161 /** 162 * {@inheritdoc} 163 */ 164 public function getId() 165 { 166 return $this->saveHandler->getId(); 167 } 168 169 /** 170 * {@inheritdoc} 171 */ 172 public function setId($id) 173 { 174 $this->saveHandler->setId($id); 175 } 176 177 /** 178 * {@inheritdoc} 179 */ 180 public function getName() 181 { 182 return $this->saveHandler->getName(); 183 } 184 185 /** 186 * {@inheritdoc} 187 */ 188 public function setName($name) 189 { 190 $this->saveHandler->setName($name); 191 } 192 193 /** 194 * {@inheritdoc} 195 */ 196 public function regenerate($destroy = false, $lifetime = null) 197 { 198 // Cannot regenerate the session ID for non-active sessions. 199 if (PHP_VERSION_ID >= 50400 && \PHP_SESSION_ACTIVE !== session_status()) { 200 return false; 201 } 202 203 // Check if session ID exists in PHP 5.3 204 if (PHP_VERSION_ID < 50400 && '' === session_id()) { 205 return false; 206 } 207 208 if (null !== $lifetime) { 209 ini_set('session.cookie_lifetime', $lifetime); 210 } 211 212 if ($destroy) { 213 $this->metadataBag->stampNew(); 214 } 215 216 $isRegenerated = session_regenerate_id($destroy); 217 218 // The reference to $_SESSION in session bags is lost in PHP7 and we need to re-create it. 219 // @see https://bugs.php.net/bug.php?id=70013 220 $this->loadSession(); 221 222 return $isRegenerated; 223 } 224 225 /** 226 * {@inheritdoc} 227 */ 228 public function save() 229 { 230 session_write_close(); 231 232 if (!$this->saveHandler->isWrapper() && !$this->saveHandler->isSessionHandlerInterface()) { 233 // This condition matches only PHP 5.3 with internal save handlers 234 $this->saveHandler->setActive(false); 235 } 236 237 $this->closed = true; 238 $this->started = false; 239 } 240 241 /** 242 * {@inheritdoc} 243 */ 244 public function clear() 245 { 246 // clear out the bags 247 foreach ($this->bags as $bag) { 248 $bag->clear(); 249 } 250 251 // clear out the session 252 $_SESSION = array(); 253 254 // reconnect the bags to the session 255 $this->loadSession(); 256 } 257 258 /** 259 * {@inheritdoc} 260 */ 261 public function registerBag(SessionBagInterface $bag) 262 { 263 if ($this->started) { 264 throw new \LogicException('Cannot register a bag when the session is already started.'); 265 } 266 267 $this->bags[$bag->getName()] = $bag; 268 } 269 270 /** 271 * {@inheritdoc} 272 */ 273 public function getBag($name) 274 { 275 if (!isset($this->bags[$name])) { 276 throw new \InvalidArgumentException(sprintf('The SessionBagInterface %s is not registered.', $name)); 277 } 278 279 if ($this->saveHandler->isActive() && !$this->started) { 280 $this->loadSession(); 281 } elseif (!$this->started) { 282 $this->start(); 283 } 284 285 return $this->bags[$name]; 286 } 287 288 /** 289 * Sets the MetadataBag. 290 * 291 * @param MetadataBag $metaBag 292 */ 293 public function setMetadataBag(MetadataBag $metaBag = null) 294 { 295 if (null === $metaBag) { 296 $metaBag = new MetadataBag(); 297 } 298 299 $this->metadataBag = $metaBag; 300 } 301 302 /** 303 * Gets the MetadataBag. 304 * 305 * @return MetadataBag 306 */ 307 public function getMetadataBag() 308 { 309 return $this->metadataBag; 310 } 311 312 /** 313 * {@inheritdoc} 314 */ 315 public function isStarted() 316 { 317 return $this->started; 318 } 319 320 /** 321 * Sets session.* ini variables. 322 * 323 * For convenience we omit 'session.' from the beginning of the keys. 324 * Explicitly ignores other ini keys. 325 * 326 * @param array $options Session ini directives array(key => value). 327 * 328 * @see http://php.net/session.configuration 329 */ 330 public function setOptions(array $options) 331 { 332 $validOptions = array_flip(array( 333 'cache_limiter', 'cookie_domain', 'cookie_httponly', 334 'cookie_lifetime', 'cookie_path', 'cookie_secure', 335 'entropy_file', 'entropy_length', 'gc_divisor', 336 'gc_maxlifetime', 'gc_probability', 'hash_bits_per_character', 337 'hash_function', 'name', 'referer_check', 338 'serialize_handler', 'use_cookies', 339 'use_only_cookies', 'use_trans_sid', 'upload_progress.enabled', 340 'upload_progress.cleanup', 'upload_progress.prefix', 'upload_progress.name', 341 'upload_progress.freq', 'upload_progress.min-freq', 'url_rewriter.tags', 342 )); 343 344 foreach ($options as $key => $value) { 345 if (isset($validOptions[$key])) { 346 ini_set('session.'.$key, $value); 347 } 348 } 349 } 350 351 /** 352 * Registers session save handler as a PHP session handler. 353 * 354 * To use internal PHP session save handlers, override this method using ini_set with 355 * session.save_handler and session.save_path e.g. 356 * 357 * ini_set('session.save_handler', 'files'); 358 * ini_set('session.save_path', '/tmp'); 359 * 360 * or pass in a NativeSessionHandler instance which configures session.save_handler in the 361 * constructor, for a template see NativeFileSessionHandler or use handlers in 362 * composer package drak/native-session 363 * 364 * @see http://php.net/session-set-save-handler 365 * @see http://php.net/sessionhandlerinterface 366 * @see http://php.net/sessionhandler 367 * @see http://github.com/drak/NativeSession 368 * 369 * @param AbstractProxy|NativeSessionHandler|\SessionHandlerInterface|null $saveHandler 370 * 371 * @throws \InvalidArgumentException 372 */ 373 public function setSaveHandler($saveHandler = null) 374 { 375 if (!$saveHandler instanceof AbstractProxy && 376 !$saveHandler instanceof NativeSessionHandler && 377 !$saveHandler instanceof \SessionHandlerInterface && 378 null !== $saveHandler) { 379 throw new \InvalidArgumentException('Must be instance of AbstractProxy or NativeSessionHandler; implement \SessionHandlerInterface; or be null.'); 380 } 381 382 // Wrap $saveHandler in proxy and prevent double wrapping of proxy 383 if (!$saveHandler instanceof AbstractProxy && $saveHandler instanceof \SessionHandlerInterface) { 384 $saveHandler = new SessionHandlerProxy($saveHandler); 385 } elseif (!$saveHandler instanceof AbstractProxy) { 386 $saveHandler = PHP_VERSION_ID >= 50400 ? 387 new SessionHandlerProxy(new \SessionHandler()) : new NativeProxy(); 388 } 389 $this->saveHandler = $saveHandler; 390 391 if ($this->saveHandler instanceof \SessionHandlerInterface) { 392 if (PHP_VERSION_ID >= 50400) { 393 session_set_save_handler($this->saveHandler, false); 394 } else { 395 session_set_save_handler( 396 array($this->saveHandler, 'open'), 397 array($this->saveHandler, 'close'), 398 array($this->saveHandler, 'read'), 399 array($this->saveHandler, 'write'), 400 array($this->saveHandler, 'destroy'), 401 array($this->saveHandler, 'gc') 402 ); 403 } 404 } 405 } 406 407 /** 408 * Load the session with attributes. 409 * 410 * After starting the session, PHP retrieves the session from whatever handlers 411 * are set to (either PHP's internal, or a custom save handler set with session_set_save_handler()). 412 * PHP takes the return value from the read() handler, unserializes it 413 * and populates $_SESSION with the result automatically. 414 * 415 * @param array|null $session 416 */ 417 protected function loadSession(array &$session = null) 418 { 419 if (null === $session) { 420 $session = &$_SESSION; 421 } 422 423 $bags = array_merge($this->bags, array($this->metadataBag)); 424 425 foreach ($bags as $bag) { 426 $key = $bag->getStorageKey(); 427 $session[$key] = isset($session[$key]) ? $session[$key] : array(); 428 $bag->initialize($session[$key]); 429 } 430 431 $this->started = true; 432 $this->closed = false; 433 } 434 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |