Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

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: 02.04.2025, 15:04 - 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