See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
1 <?php 2 /* 3 * Copyright 2015-present MongoDB, Inc. 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * https://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 namespace MongoDB; 19 20 use Iterator; 21 use Jean85\PrettyVersions; 22 use MongoDB\Driver\ClientEncryption; 23 use MongoDB\Driver\Exception\InvalidArgumentException as DriverInvalidArgumentException; 24 use MongoDB\Driver\Exception\RuntimeException as DriverRuntimeException; 25 use MongoDB\Driver\Manager; 26 use MongoDB\Driver\ReadConcern; 27 use MongoDB\Driver\ReadPreference; 28 use MongoDB\Driver\Session; 29 use MongoDB\Driver\WriteConcern; 30 use MongoDB\Exception\InvalidArgumentException; 31 use MongoDB\Exception\UnexpectedValueException; 32 use MongoDB\Exception\UnsupportedException; 33 use MongoDB\Model\BSONArray; 34 use MongoDB\Model\BSONDocument; 35 use MongoDB\Model\DatabaseInfoIterator; 36 use MongoDB\Operation\DropDatabase; 37 use MongoDB\Operation\ListDatabaseNames; 38 use MongoDB\Operation\ListDatabases; 39 use MongoDB\Operation\Watch; 40 use Throwable; 41 42 use function is_array; 43 use function is_string; 44 45 class Client 46 { 47 public const DEFAULT_URI = 'mongodb://127.0.0.1/'; 48 49 /** @var array */ 50 private static $defaultTypeMap = [ 51 'array' => BSONArray::class, 52 'document' => BSONDocument::class, 53 'root' => BSONDocument::class, 54 ]; 55 56 /** @var string */ 57 private static $handshakeSeparator = ' / '; 58 59 /** @var string|null */ 60 private static $version; 61 62 /** @var Manager */ 63 private $manager; 64 65 /** @var ReadConcern */ 66 private $readConcern; 67 68 /** @var ReadPreference */ 69 private $readPreference; 70 71 /** @var string */ 72 private $uri; 73 74 /** @var array */ 75 private $typeMap; 76 77 /** @var WriteConcern */ 78 private $writeConcern; 79 80 /** 81 * Constructs a new Client instance. 82 * 83 * This is the preferred class for connecting to a MongoDB server or 84 * cluster of servers. It serves as a gateway for accessing individual 85 * databases and collections. 86 * 87 * Supported driver-specific options: 88 * 89 * * typeMap (array): Default type map for cursors and BSON documents. 90 * 91 * Other options are documented in MongoDB\Driver\Manager::__construct(). 92 * 93 * @see https://mongodb.com/docs/manual/reference/connection-string/ 94 * @see https://php.net/manual/en/mongodb-driver-manager.construct.php 95 * @see https://php.net/manual/en/mongodb.persistence.php#mongodb.persistence.typemaps 96 * @param string|null $uri MongoDB connection string. If none is provided, this defaults to self::DEFAULT_URI. 97 * @param array $uriOptions Additional connection string options 98 * @param array $driverOptions Driver-specific options 99 * @throws InvalidArgumentException for parameter/option parsing errors 100 * @throws DriverInvalidArgumentException for parameter/option parsing errors in the driver 101 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 102 */ 103 public function __construct(?string $uri = null, array $uriOptions = [], array $driverOptions = []) 104 { 105 $driverOptions += ['typeMap' => self::$defaultTypeMap]; 106 107 if (! is_array($driverOptions['typeMap'])) { 108 throw InvalidArgumentException::invalidType('"typeMap" driver option', $driverOptions['typeMap'], 'array'); 109 } 110 111 if (isset($driverOptions['autoEncryption']['keyVaultClient'])) { 112 if ($driverOptions['autoEncryption']['keyVaultClient'] instanceof self) { 113 $driverOptions['autoEncryption']['keyVaultClient'] = $driverOptions['autoEncryption']['keyVaultClient']->manager; 114 } elseif (! $driverOptions['autoEncryption']['keyVaultClient'] instanceof Manager) { 115 throw InvalidArgumentException::invalidType('"keyVaultClient" autoEncryption option', $driverOptions['autoEncryption']['keyVaultClient'], [self::class, Manager::class]); 116 } 117 } 118 119 $driverOptions['driver'] = $this->mergeDriverInfo($driverOptions['driver'] ?? []); 120 121 $this->uri = $uri ?? self::DEFAULT_URI; 122 $this->typeMap = $driverOptions['typeMap']; 123 124 unset($driverOptions['typeMap']); 125 126 $this->manager = new Manager($uri, $uriOptions, $driverOptions); 127 $this->readConcern = $this->manager->getReadConcern(); 128 $this->readPreference = $this->manager->getReadPreference(); 129 $this->writeConcern = $this->manager->getWriteConcern(); 130 } 131 132 /** 133 * Return internal properties for debugging purposes. 134 * 135 * @see https://php.net/manual/en/language.oop5.magic.php#language.oop5.magic.debuginfo 136 * @return array 137 */ 138 public function __debugInfo() 139 { 140 return [ 141 'manager' => $this->manager, 142 'uri' => $this->uri, 143 'typeMap' => $this->typeMap, 144 'writeConcern' => $this->writeConcern, 145 ]; 146 } 147 148 /** 149 * Select a database. 150 * 151 * Note: databases whose names contain special characters (e.g. "-") may 152 * be selected with complex syntax (e.g. $client->{"that-database"}) or 153 * {@link selectDatabase()}. 154 * 155 * @see https://php.net/oop5.overloading#object.get 156 * @see https://php.net/types.string#language.types.string.parsing.complex 157 * @param string $databaseName Name of the database to select 158 * @return Database 159 */ 160 public function __get(string $databaseName) 161 { 162 return $this->selectDatabase($databaseName); 163 } 164 165 /** 166 * Return the connection string (i.e. URI). 167 * 168 * @return string 169 */ 170 public function __toString() 171 { 172 return $this->uri; 173 } 174 175 /** 176 * Returns a ClientEncryption instance for explicit encryption and decryption 177 * 178 * @param array $options Encryption options 179 * 180 * @return ClientEncryption 181 */ 182 public function createClientEncryption(array $options) 183 { 184 if (isset($options['keyVaultClient'])) { 185 if ($options['keyVaultClient'] instanceof self) { 186 $options['keyVaultClient'] = $options['keyVaultClient']->manager; 187 } elseif (! $options['keyVaultClient'] instanceof Manager) { 188 throw InvalidArgumentException::invalidType('"keyVaultClient" option', $options['keyVaultClient'], [self::class, Manager::class]); 189 } 190 } 191 192 return $this->manager->createClientEncryption($options); 193 } 194 195 /** 196 * Drop a database. 197 * 198 * @see DropDatabase::__construct() for supported options 199 * @param string $databaseName Database name 200 * @param array $options Additional options 201 * @return array|object Command result document 202 * @throws UnsupportedException if options are unsupported on the selected server 203 * @throws InvalidArgumentException for parameter/option parsing errors 204 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 205 */ 206 public function dropDatabase(string $databaseName, array $options = []) 207 { 208 if (! isset($options['typeMap'])) { 209 $options['typeMap'] = $this->typeMap; 210 } 211 212 $server = select_server($this->manager, $options); 213 214 if (! isset($options['writeConcern']) && ! is_in_transaction($options)) { 215 $options['writeConcern'] = $this->writeConcern; 216 } 217 218 $operation = new DropDatabase($databaseName, $options); 219 220 return $operation->execute($server); 221 } 222 223 /** 224 * Return the Manager. 225 * 226 * @return Manager 227 */ 228 public function getManager() 229 { 230 return $this->manager; 231 } 232 233 /** 234 * Return the read concern for this client. 235 * 236 * @see https://php.net/manual/en/mongodb-driver-readconcern.isdefault.php 237 * @return ReadConcern 238 */ 239 public function getReadConcern() 240 { 241 return $this->readConcern; 242 } 243 244 /** 245 * Return the read preference for this client. 246 * 247 * @return ReadPreference 248 */ 249 public function getReadPreference() 250 { 251 return $this->readPreference; 252 } 253 254 /** 255 * Return the type map for this client. 256 * 257 * @return array 258 */ 259 public function getTypeMap() 260 { 261 return $this->typeMap; 262 } 263 264 /** 265 * Return the write concern for this client. 266 * 267 * @see https://php.net/manual/en/mongodb-driver-writeconcern.isdefault.php 268 * @return WriteConcern 269 */ 270 public function getWriteConcern() 271 { 272 return $this->writeConcern; 273 } 274 275 /** 276 * List database names. 277 * 278 * @see ListDatabaseNames::__construct() for supported options 279 * @throws UnexpectedValueException if the command response was malformed 280 * @throws InvalidArgumentException for parameter/option parsing errors 281 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 282 */ 283 public function listDatabaseNames(array $options = []): Iterator 284 { 285 $operation = new ListDatabaseNames($options); 286 $server = select_server($this->manager, $options); 287 288 return $operation->execute($server); 289 } 290 291 /** 292 * List databases. 293 * 294 * @see ListDatabases::__construct() for supported options 295 * @return DatabaseInfoIterator 296 * @throws UnexpectedValueException if the command response was malformed 297 * @throws InvalidArgumentException for parameter/option parsing errors 298 * @throws DriverRuntimeException for other driver errors (e.g. connection errors) 299 */ 300 public function listDatabases(array $options = []) 301 { 302 $operation = new ListDatabases($options); 303 $server = select_server($this->manager, $options); 304 305 return $operation->execute($server); 306 } 307 308 /** 309 * Select a collection. 310 * 311 * @see Collection::__construct() for supported options 312 * @param string $databaseName Name of the database containing the collection 313 * @param string $collectionName Name of the collection to select 314 * @param array $options Collection constructor options 315 * @return Collection 316 * @throws InvalidArgumentException for parameter/option parsing errors 317 */ 318 public function selectCollection(string $databaseName, string $collectionName, array $options = []) 319 { 320 $options += ['typeMap' => $this->typeMap]; 321 322 return new Collection($this->manager, $databaseName, $collectionName, $options); 323 } 324 325 /** 326 * Select a database. 327 * 328 * @see Database::__construct() for supported options 329 * @param string $databaseName Name of the database to select 330 * @param array $options Database constructor options 331 * @return Database 332 * @throws InvalidArgumentException for parameter/option parsing errors 333 */ 334 public function selectDatabase(string $databaseName, array $options = []) 335 { 336 $options += ['typeMap' => $this->typeMap]; 337 338 return new Database($this->manager, $databaseName, $options); 339 } 340 341 /** 342 * Start a new client session. 343 * 344 * @see https://php.net/manual/en/mongodb-driver-manager.startsession.php 345 * @param array $options Session options 346 * @return Session 347 */ 348 public function startSession(array $options = []) 349 { 350 return $this->manager->startSession($options); 351 } 352 353 /** 354 * Create a change stream for watching changes to the cluster. 355 * 356 * @see Watch::__construct() for supported options 357 * @param array $pipeline List of pipeline operations 358 * @param array $options Command options 359 * @return ChangeStream 360 * @throws InvalidArgumentException for parameter/option parsing errors 361 */ 362 public function watch(array $pipeline = [], array $options = []) 363 { 364 if (! isset($options['readPreference']) && ! is_in_transaction($options)) { 365 $options['readPreference'] = $this->readPreference; 366 } 367 368 $server = select_server($this->manager, $options); 369 370 if (! isset($options['readConcern']) && ! is_in_transaction($options)) { 371 $options['readConcern'] = $this->readConcern; 372 } 373 374 if (! isset($options['typeMap'])) { 375 $options['typeMap'] = $this->typeMap; 376 } 377 378 $operation = new Watch($this->manager, null, null, $pipeline, $options); 379 380 return $operation->execute($server); 381 } 382 383 private static function getVersion(): string 384 { 385 if (self::$version === null) { 386 try { 387 self::$version = PrettyVersions::getVersion('mongodb/mongodb')->getPrettyVersion(); 388 } catch (Throwable $t) { 389 return 'unknown'; 390 } 391 } 392 393 return self::$version; 394 } 395 396 private function mergeDriverInfo(array $driver): array 397 { 398 $mergedDriver = [ 399 'name' => 'PHPLIB', 400 'version' => self::getVersion(), 401 ]; 402 403 if (isset($driver['name'])) { 404 if (! is_string($driver['name'])) { 405 throw InvalidArgumentException::invalidType('"name" handshake option', $driver['name'], 'string'); 406 } 407 408 $mergedDriver['name'] .= self::$handshakeSeparator . $driver['name']; 409 } 410 411 if (isset($driver['version'])) { 412 if (! is_string($driver['version'])) { 413 throw InvalidArgumentException::invalidType('"version" handshake option', $driver['version'], 'string'); 414 } 415 416 $mergedDriver['version'] .= self::$handshakeSeparator . $driver['version']; 417 } 418 419 if (isset($driver['platform'])) { 420 $mergedDriver['platform'] = $driver['platform']; 421 } 422 423 return $mergedDriver; 424 } 425 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body