[ Index ]

PHP Cross Reference of phpBB-3.1.12-deutsch

title

Body

[close]

/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Session/Storage/ -> NativeSessionStorage.php (source)

   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  }


Generated: Thu Jan 11 00:25:41 2018 Cross-referenced by PHPXref 0.7.1