Verzeichnisstruktur phpBB-3.3.16


Veröffentlicht
27.04.2026

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

MongoDbSessionHandler.php

Zuletzt modifiziert: 01.05.2026, 11:28 - Dateigröße: 7.55 KiB


 001  <?php
 002   
 003  /*
 004   * This file is part of the Symfony package.
 005   *
 006   * (c) Fabien Potencier <fabien@symfony.com>
 007   *
 008   * For the full copyright and license information, please view the LICENSE
 009   * file that was distributed with this source code.
 010   */
 011   
 012  namespace Symfony\Component\HttpFoundation\Session\Storage\Handler;
 013   
 014  /**
 015   * Session handler using the mongodb/mongodb package and MongoDB driver extension.
 016   *
 017   * @author Markus Bachmann <markus.bachmann@bachi.biz>
 018   *
 019   * @see https://packagist.org/packages/mongodb/mongodb
 020   * @see https://php.net/mongodb
 021   */
 022  class MongoDbSessionHandler extends AbstractSessionHandler
 023  {
 024      private $mongo;
 025   
 026      /**
 027       * @var \MongoCollection
 028       */
 029      private $collection;
 030   
 031      /**
 032       * @var array
 033       */
 034      private $options;
 035   
 036      /**
 037       * Constructor.
 038       *
 039       * List of available options:
 040       *  * database: The name of the database [required]
 041       *  * collection: The name of the collection [required]
 042       *  * id_field: The field name for storing the session id [default: _id]
 043       *  * data_field: The field name for storing the session data [default: data]
 044       *  * time_field: The field name for storing the timestamp [default: time]
 045       *  * expiry_field: The field name for storing the expiry-timestamp [default: expires_at].
 046       *
 047       * It is strongly recommended to put an index on the `expiry_field` for
 048       * garbage-collection. Alternatively it's possible to automatically expire
 049       * the sessions in the database as described below:
 050       *
 051       * A TTL collections can be used on MongoDB 2.2+ to cleanup expired sessions
 052       * automatically. Such an index can for example look like this:
 053       *
 054       *     db.<session-collection>.ensureIndex(
 055       *         { "<expiry-field>": 1 },
 056       *         { "expireAfterSeconds": 0 }
 057       *     )
 058       *
 059       * More details on: https://docs.mongodb.org/manual/tutorial/expire-data/
 060       *
 061       * If you use such an index, you can drop `gc_probability` to 0 since
 062       * no garbage-collection is required.
 063       *
 064       * @param \MongoDB\Client $mongo   A MongoDB\Client instance
 065       * @param array           $options An associative array of field options
 066       *
 067       * @throws \InvalidArgumentException When MongoClient or Mongo instance not provided
 068       * @throws \InvalidArgumentException When "database" or "collection" not provided
 069       */
 070      public function __construct($mongo, array $options)
 071      {
 072          if ($mongo instanceof \MongoClient || $mongo instanceof \Mongo) {
 073              @trigger_error(sprintf('Using %s with the legacy mongo extension is deprecated as of 3.4 and will be removed in 4.0. Use it with the mongodb/mongodb package and ext-mongodb instead.', __CLASS__), \E_USER_DEPRECATED);
 074          }
 075   
 076          if (!($mongo instanceof \MongoDB\Client || $mongo instanceof \MongoClient || $mongo instanceof \Mongo)) {
 077              throw new \InvalidArgumentException('MongoClient or Mongo instance required.');
 078          }
 079   
 080          if (!isset($options['database']) || !isset($options['collection'])) {
 081              throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler.');
 082          }
 083   
 084          $this->mongo = $mongo;
 085   
 086          $this->options = array_merge([
 087              'id_field' => '_id',
 088              'data_field' => 'data',
 089              'time_field' => 'time',
 090              'expiry_field' => 'expires_at',
 091          ], $options);
 092      }
 093   
 094      /**
 095       * {@inheritdoc}
 096       */
 097      public function close()
 098      {
 099          return true;
 100      }
 101   
 102      /**
 103       * {@inheritdoc}
 104       */
 105      protected function doDestroy($sessionId)
 106      {
 107          $methodName = $this->mongo instanceof \MongoDB\Client ? 'deleteOne' : 'remove';
 108   
 109          $this->getCollection()->$methodName([
 110              $this->options['id_field'] => $sessionId,
 111          ]);
 112   
 113          return true;
 114      }
 115   
 116      /**
 117       * {@inheritdoc}
 118       */
 119      public function gc($maxlifetime)
 120      {
 121          $methodName = $this->mongo instanceof \MongoDB\Client ? 'deleteMany' : 'remove';
 122   
 123          $this->getCollection()->$methodName([
 124              $this->options['expiry_field'] => ['$lt' => $this->createDateTime()],
 125          ]);
 126   
 127          return true;
 128      }
 129   
 130      /**
 131       * {@inheritdoc}
 132       */
 133      protected function doWrite($sessionId, $data)
 134      {
 135          $expiry = $this->createDateTime(time() + (int) ini_get('session.gc_maxlifetime'));
 136   
 137          $fields = [
 138              $this->options['time_field'] => $this->createDateTime(),
 139              $this->options['expiry_field'] => $expiry,
 140          ];
 141   
 142          $options = ['upsert' => true];
 143   
 144          if ($this->mongo instanceof \MongoDB\Client) {
 145              $fields[$this->options['data_field']] = new \MongoDB\BSON\Binary($data, \MongoDB\BSON\Binary::TYPE_OLD_BINARY);
 146          } else {
 147              $fields[$this->options['data_field']] = new \MongoBinData($data, \MongoBinData::BYTE_ARRAY);
 148              $options['multiple'] = false;
 149          }
 150   
 151          $methodName = $this->mongo instanceof \MongoDB\Client ? 'updateOne' : 'update';
 152   
 153          $this->getCollection()->$methodName(
 154              [$this->options['id_field'] => $sessionId],
 155              ['$set' => $fields],
 156              $options
 157          );
 158   
 159          return true;
 160      }
 161   
 162      /**
 163       * {@inheritdoc}
 164       */
 165      public function updateTimestamp($sessionId, $data)
 166      {
 167          $expiry = $this->createDateTime(time() + (int) ini_get('session.gc_maxlifetime'));
 168   
 169          if ($this->mongo instanceof \MongoDB\Client) {
 170              $methodName = 'updateOne';
 171              $options = [];
 172          } else {
 173              $methodName = 'update';
 174              $options = ['multiple' => false];
 175          }
 176   
 177          $this->getCollection()->$methodName(
 178              [$this->options['id_field'] => $sessionId],
 179              ['$set' => [
 180                  $this->options['time_field'] => $this->createDateTime(),
 181                  $this->options['expiry_field'] => $expiry,
 182              ]],
 183              $options
 184          );
 185   
 186          return true;
 187      }
 188   
 189      /**
 190       * {@inheritdoc}
 191       */
 192      protected function doRead($sessionId)
 193      {
 194          $dbData = $this->getCollection()->findOne([
 195              $this->options['id_field'] => $sessionId,
 196              $this->options['expiry_field'] => ['$gte' => $this->createDateTime()],
 197          ]);
 198   
 199          if (null === $dbData) {
 200              return '';
 201          }
 202   
 203          if ($dbData[$this->options['data_field']] instanceof \MongoDB\BSON\Binary) {
 204              return $dbData[$this->options['data_field']]->getData();
 205          }
 206   
 207          return $dbData[$this->options['data_field']]->bin;
 208      }
 209   
 210      /**
 211       * Return a "MongoCollection" instance.
 212       *
 213       * @return \MongoCollection
 214       */
 215      private function getCollection()
 216      {
 217          if (null === $this->collection) {
 218              $this->collection = $this->mongo->selectCollection($this->options['database'], $this->options['collection']);
 219          }
 220   
 221          return $this->collection;
 222      }
 223   
 224      /**
 225       * Return a Mongo instance.
 226       *
 227       * @return \Mongo|\MongoClient|\MongoDB\Client
 228       */
 229      protected function getMongo()
 230      {
 231          return $this->mongo;
 232      }
 233   
 234      /**
 235       * Create a date object using the class appropriate for the current mongo connection.
 236       *
 237       * Return an instance of a MongoDate or \MongoDB\BSON\UTCDateTime
 238       *
 239       * @param int $seconds An integer representing UTC seconds since Jan 1 1970.  Defaults to now.
 240       *
 241       * @return \MongoDate|\MongoDB\BSON\UTCDateTime
 242       */
 243      private function createDateTime($seconds = null)
 244      {
 245          if (null === $seconds) {
 246              $seconds = time();
 247          }
 248   
 249          if ($this->mongo instanceof \MongoDB\Client) {
 250              return new \MongoDB\BSON\UTCDateTime($seconds * 1000);
 251          }
 252   
 253          return new \MongoDate($seconds);
 254      }
 255  }
 256