[ Index ] |
PHP Cross Reference of phpBB-3.3.14-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\Handler; 13 14 /** 15 * Session handler using the mongodb/mongodb package and MongoDB driver extension. 16 * 17 * @author Markus Bachmann <markus.bachmann@bachi.biz> 18 * 19 * @see https://packagist.org/packages/mongodb/mongodb 20 * @see https://php.net/mongodb 21 */ 22 class MongoDbSessionHandler extends AbstractSessionHandler 23 { 24 private $mongo; 25 26 /** 27 * @var \MongoCollection 28 */ 29 private $collection; 30 31 /** 32 * @var array 33 */ 34 private $options; 35 36 /** 37 * Constructor. 38 * 39 * List of available options: 40 * * database: The name of the database [required] 41 * * collection: The name of the collection [required] 42 * * id_field: The field name for storing the session id [default: _id] 43 * * data_field: The field name for storing the session data [default: data] 44 * * time_field: The field name for storing the timestamp [default: time] 45 * * expiry_field: The field name for storing the expiry-timestamp [default: expires_at]. 46 * 47 * It is strongly recommended to put an index on the `expiry_field` for 48 * garbage-collection. Alternatively it's possible to automatically expire 49 * the sessions in the database as described below: 50 * 51 * A TTL collections can be used on MongoDB 2.2+ to cleanup expired sessions 52 * automatically. Such an index can for example look like this: 53 * 54 * db.<session-collection>.ensureIndex( 55 * { "<expiry-field>": 1 }, 56 * { "expireAfterSeconds": 0 } 57 * ) 58 * 59 * More details on: https://docs.mongodb.org/manual/tutorial/expire-data/ 60 * 61 * If you use such an index, you can drop `gc_probability` to 0 since 62 * no garbage-collection is required. 63 * 64 * @param \MongoDB\Client $mongo A MongoDB\Client instance 65 * @param array $options An associative array of field options 66 * 67 * @throws \InvalidArgumentException When MongoClient or Mongo instance not provided 68 * @throws \InvalidArgumentException When "database" or "collection" not provided 69 */ 70 public function __construct($mongo, array $options) 71 { 72 if ($mongo instanceof \MongoClient || $mongo instanceof \Mongo) { 73 @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); 74 } 75 76 if (!($mongo instanceof \MongoDB\Client || $mongo instanceof \MongoClient || $mongo instanceof \Mongo)) { 77 throw new \InvalidArgumentException('MongoClient or Mongo instance required.'); 78 } 79 80 if (!isset($options['database']) || !isset($options['collection'])) { 81 throw new \InvalidArgumentException('You must provide the "database" and "collection" option for MongoDBSessionHandler.'); 82 } 83 84 $this->mongo = $mongo; 85 86 $this->options = array_merge([ 87 'id_field' => '_id', 88 'data_field' => 'data', 89 'time_field' => 'time', 90 'expiry_field' => 'expires_at', 91 ], $options); 92 } 93 94 /** 95 * {@inheritdoc} 96 */ 97 public function close() 98 { 99 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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |