# Connecting

Connecting to MongoDB can be as easy as `new MongoClient`, but there are many additional options and configurations. The documentation for `MongoClient::__construct` covers all of the API options, but this page gives some more details and advice for practical use cases.

## Authentication

If MongoDB is started with the `--auth` or `--keyFile` options, you must authenticate before you can do any operations with the driver. You may authenticate a connection by specifying the username and password in either the connection URI or the `"username"` and `"password"` options for `MongoClient::__construct`.

### Authenticating against the "admin" database

    <?php
    // Specifying the username and password in the connection URI (preferred)
    $m = new MongoClient("mongodb://${username}:${password}@localhost");

    // Specifying the username and password via the options array (alternative)
    $m = new MongoClient("mongodb://localhost", array("username" => $username, "password" => $password));
    ?>

By default, the driver will authenticate against the `admin` database. You may authenticate against a different database by specifying it in either the connection URI or the `"db"` option for `MongoClient::__construct`.

### Authenticating against normal databases

    <?php
    // Specifying the authentication database in the connection URI (preferred)
    $m = new MongoClient("mongodb://${username}:${password}@localhost/myDatabase");

    // Specifying the authentication database via the options array (alternative)
    $m = new MongoClient("mongodb://${username}:${password}@localhost", array("db" => "myDatabase"));
    ?>

If your connection is dropped, the driver will automatically attempt to reconnect and reauthenticate you.

## Replica Sets

To connect to a replica set, specify one or more members of the set and use the `"replicaSet"` option. Multiple servers may be delimited by a comma.

### ReplicaSet seedlist

    <?php
    // Using multiple servers as the seed list (prefered)
    $m = new MongoClient("mongodb://rs1.example.com:27017,rs2.example.com:27017/?replicaSet=myReplSetName");

    // Using one server as the seed list
    $m = new MongoClient("mongodb://rs1.example.com:27017", array("replicaSet" => "myReplSetName"));

    // Using multiple servers as the seed list
    $m = new MongoClient("mongodb://rs1.example.com:27017,rs2.example.com:27017", array("replicaSet" => "myReplSetName"));
    ?>

The PHP driver will query the database server(s) listed to determine the primary. So long as it can connect to at least one host listed and find a primary, the connection will succeed. If it cannot make a connection to any servers listed or cannot find a primary, a `MongoConnectionException` will be thrown.

You should always provide a seedlist with more than one member of the ReplicaSet. For highest availability you should seed with at least one server from each of your datacenters.

The host names that you specify here must match the names as given in the replica set configuration because the driver uses the name as specified in the replica set configuration as identifier in its internal mapping. Specifying (for example) the IP address instead of the configured host name makes that the driver keeps a connection for both the host name and its accompanying IP address.

The driver does not support connecting to different replica sets with the same name. This extends beyond one script so make sure to have separate names for each of your replica sets. That also means that you can not do this:

#### Wrong replica set name duplication

    <?php
    $m = new MongoClient("mongodb://devserver1,devserver2,devserver3/?replicaSet=repset");
    $m = new MongoClient("mongodb://prodserver1,prodserver2,prodserver3/?replicaSet=repset");
    ?>

Instead, you need to have two different names for your replica sets:

#### Correct use of two replica set names

    <?php
    $m = new MongoClient("mongodb://devserver1,devserver2,devserver3/?replicaSet=devset");
    $m = new MongoClient("mongodb://prodserver1,prodserver2,prodserver3/?replicaSet=prodset");
    ?>

If the primary becomes unavailable, an election will take place and a secondary will be promoted to the role of primary (unless a majority vote cannot be established). During this time (20-60 seconds), the connection will not be able to perform any write operations and attempts to do so will result in an exception. Connections to secondaries will still be able to perform reads.

The default Read Preference is to only read from the primary. During the election process there is no primary, and all read will therefore fail.

It is recommended to use `MongoClient::RP_PRIMARY_PREFERRED` Read Preference for applications that require high availability for reads, as reads will only be executed on the secondaries when there simply isn't a primary available.

Once a primary is elected, attempting to perform a read or write will allow the driver to detect the new primary. The driver will make this its primary database connection and continue operating normally.

The health and state of a secondary is checked every 5 seconds (configurable with mongo.ping_interval) or when the next operation occurs after 5 seconds. It will also recheck the configuration when the driver has a problem reaching a server.

Replica set failovers are checked every 60 seconds (configurable with mongo.is_master_interval), and whenever a write operation fails when using acknowledged writes.

Secondaries may be behind the primary in operations, so your application must be able to handle out-of-date data when using Read Preferences other then `MongoClient::RP_PRIMARY`.

For more information on replica sets, see the core documentation.

&reftitle.seealso;

- mongo.readpreferences
- mongo.writeconcerns

&reftitle.changelog;

&Version; | &Description;
1.0.9 | Added support for connecting to ReplicaSet and automatic failover.

## Sharding

To connect to a shard cluster, specify the address of one or more `mongos` instances in the connection string. Multiple servers may be delimited by a comma.

    <?php
    // Using one server as the seed list
    $m = new MongoClient("mongodb://mongos1.example.com:27017");

    // Using multiple servers as the seed list
    $m = new MongoClient("mongodb://mongos1.example.com:27017,mongos2.example.com:27017");
    ?>

Regardless of whether each shard is a stand-alone `mongod` server or a full replica set, the driver's connection process is the same. All database communication will be routed through `mongos`.

For more information on sharding with MongoDB, see the sharding documentation.

## Domain Socket Support

MongoDB has built-in support for via Unix Domain Sockets and will open the socket on startup, by default located in `/tmp/mongodb-<port>.sock.`.

To connect to the socket file, specify the path in your MongoDB connection string:

    <?php
    $m = new MongoClient("mongodb:///tmp/mongo-27017.sock");
    ?>

If you would like to authenticate against a database (as described above) with a socket file, you must specify a port of `0` so that the connection string parser can detect the end of the socket path. Alternatively, you can use the constructor options.

    <?php
    $m = new MongoClient("mongodb://username:password@/tmp/mongo-27017.sock:0/foo");
    ?>

&reftitle.changelog;

&Version; | &Description;
1.0.9 | Added support for Unix Domain Sockets.

## Connection Pooling (version 1.2.0-1.2.12 *only*)

This section is no longer relevant as of the 1.3.0 release of the driver and only serves as a historical information on how the pooling used to work.

The latest versions of the driver have no concept of pooling anymore and will maintain only one connection per process, for each connection type (ReplicaSet/standalone/mongos), for each credentials combination.

Creating connections is one of the most heavyweight things that the driver does. It can take hundreds of milliseconds to set up a connection correctly, even on a fast network. Thus, the driver tries to minimize the number of new connections created by reusing connections from a pool.

When a user creates a new instance of `MongoClient`, all necessary connections will be taken from their pools (replica sets may require multiple connections, one for each member of the set). When the `MongoClient` instance goes out of scope, the connections will be returned to the pool. When the PHP process exits, all connections in the pools will be closed.

### "Why do I have so many open connections?"

Connection pools can generate a large number of connections. This is expected and, using a little arithmetic, you can figure out how many connections will be created. There are three factors in determining the total number of connections:

- `connections_per_pool`

  Each connection pool will create, by default, an unlimited number of connections. One might assume that this is a problem: if it can create an unlimited number of connections, couldn't it create thousands and the server would run out of file descriptors? In practice, this is unlikely, as unused connections are returned to the pool to be used later, so future connections will use the same connection instead of creating a new one. Unless you create thousands of connections at once without letting any go out of scope, the number of connections open should stay at a reasonable number.

  You can see how many connections you have in a pool using the `MongoPool::info` function. Add up the "in use" and "in pool" fields for a given server. That is the total number of connections for that pool.

- `pools_per_process`

  Each MongoDB server address you're connecting to gets its own connection pool. For example, if your local hostname is "example.net", connecting to "example.net:27017", "localhost:27017", and "/tmp/mongodb-27017.sock" will create three connection pools. You can see how many connection pools you have open using `MongoPool::info`.

- `processes`

  Each PHP process has a separate set of pools. PHP-FPM and Apache generally create between 6 and a couple of dozen PHP worker children. Check your settings to see what the max number of PHP processes is that can be spawned.

  If you are using PHP-FPM, estimating the number of connections can be tricky because it will spawn more PHP-FPM workers under heavy load. To be on the safe side, look at the `max_children` parameter or add up `spare_servers` + `start_servers` (choose whichever number is higher). That will indicate how many PHP processes (i.e. sets of pools) you should plan for.

The three variables above can be multiplied together to give the max number of connections expected: `connections_per_pool` * `pools_per_process` * `processes`. Note that `connections_per_pool` can be different for different pools, so `connections_per_pool` should be the max.

For example, suppose we're getting 30 connections per pool, 10 pools per PHP process, and 128 PHP processes. Then we can expect 38400 connections from this machine. Thus, we should set this machine's file descriptor limit to be high enough to handle all of these connections or it may run out of file descriptors.

See `MongoPool` for more information on connection pooling.

## Persistent Connections (version up to 1.1.4 *only*)

This section is not relevant for 1.2.0+. In 1.2.0+, connections are always persistent and managed automatically by the driver. If you are using a 1.2.x release (but not 1.3.x or later), see `MongoPool` for more information on pooling.

Creating new connection to the database is very slow. To minimize the number of connections that you need to make, you can use persistent connections. A persistent connection is saved by PHP, so you can use the same connection for multiple requests.

For example, this simple program connects to the database 1000 times:

    <?php

    for ($i=0; $i<1000; $i++) {
      $m = new MongoClient();
    }

    ?>

It takes approximately 18 seconds to execute. If we change it to use a persistent connection:

    <?php

    for ($i=0; $i<1000; $i++) {
      $m = new MongoClient("localhost:27017", array("persist" => "x"));
    }

    ?>

...it takes less than .02 seconds to execute, as it only makes one database connection.

Persistent connections need an identifier string (which is "x" in the above example) to uniquely identify them. For a persistent connection to be used, the hostname, port, persist string, and authentication credentials (username, password and database, if given) must match an existing persistent connection. Otherwise, a new connection will be created with this identifying information.

Persistent connections are highly recommended and should always be used in production unless there is a compelling reason not to. Most of the reasons that they are not recommended for relational databases are irrelevant to MongoDB.