diff --git a/.gitignore b/.gitignore
index c50788aa..3bef116c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,7 +3,6 @@ build/*
build
*~
*giza.log
-source/*
backups/*
vendor/
composer.lock
diff --git a/netlify.toml b/netlify.toml
index d9fb7a2c..2d0a3b98 100644
--- a/netlify.toml
+++ b/netlify.toml
@@ -5,6 +5,5 @@ name = "snooty-cache-plugin"
# set in your site’s Branches settings in the UI will inherit
# these settings.
[build]
-
publish = "snooty/public"
command = ". ./build.sh"
diff --git a/snooty.toml b/snooty.toml
index a08a8d41..aa728e0c 100644
--- a/snooty.toml
+++ b/snooty.toml
@@ -1,7 +1,11 @@
name = "php-library"
title = "PHP Library Manual"
-intersphinx = ["https://www.mongodb.com/docs/manual/objects.inv"]
+intersphinx = [
+ "https://www.mongodb.com/docs/manual/objects.inv",
+ "https://www.mongodb.com/docs/drivers/objects.inv",
+ "https://www.mongodb.com/docs/atlas/objects.inv",
+]
toc_landing_pages = [
"/reference/class/MongoDBClient",
@@ -17,10 +21,31 @@ toc_landing_pages = [
"/reference/class/MongoDBModelCollectionInfo",
"/reference/class/MongoDBModelDatabaseInfo",
"/reference/class/MongoDBModelIndexInfo",
+ "/get-started",
+ "/connect",
+ "/read",
+ "/databases-collections",
+ "/write",
+ "/indexes",
+ "/security",
+ "/data-formats",
+ "/upgrade",
]
+sharedinclude_root = "https://raw.githubusercontent.com/10gen/docs-shared/main/"
+
[substitutions]
php-library = "MongoDB PHP Library"
[constants]
php-library = "MongoDB PHP Library"
+extension-short = "PHP extension"
+mdb-server = "MongoDB Server"
+stable-api = "Stable API"
+library-short = "PHP library"
+driver-short = "{+library-short+}"
+api = "https://www.mongodb.com/docs/php-library/current/reference"
+php-manual = "https://www.php.net/manual/en"
+string-data-type = "``string``"
+bool-data-type = "``bool``"
+int-data-type = "``int``"
diff --git a/source/aggregation.txt b/source/aggregation.txt
new file mode 100644
index 00000000..96e7f63e
--- /dev/null
+++ b/source/aggregation.txt
@@ -0,0 +1,205 @@
+.. _php-aggregation:
+
+====================================
+Transform Your Data with Aggregation
+====================================
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: code example, transform, computed, pipeline
+ :description: Learn how to use the PHP library to perform aggregation operations.
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+.. TODO:
+ .. toctree::
+ :titlesonly:
+ :maxdepth: 1
+
+ /aggregation/aggregation-tutorials
+
+Overview
+--------
+
+In this guide, you can learn how to use the {+php-library+} to perform
+**aggregation operations**.
+
+Aggregation operations process data in your MongoDB collections and
+return computed results. The MongoDB Aggregation framework, which is
+part of the Query API, is modeled on the concept of data processing
+pipelines. Documents enter a pipeline that contains one or more stages,
+and this pipeline transforms the documents into an aggregated result.
+
+An aggregation operation is similar to a car factory. A car factory has
+an assembly line, which contains assembly stations with specialized
+tools to do specific jobs, like drills and welders. Raw parts enter the
+factory, and then the assembly line transforms and assembles them into a
+finished product.
+
+The **aggregation pipeline** is the assembly line, **aggregation stages** are the
+assembly stations, and **operator expressions** are the
+specialized tools.
+
+Aggregation Versus Find Operations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can use find operations to perform the following actions:
+
+- Select which documents to return
+- Select which fields to return
+- Sort the results
+
+You can use aggregation operations to perform the following actions:
+
+- Run find operations
+- Rename fields
+- Calculate fields
+- Summarize data
+- Group values
+
+Limitations
+~~~~~~~~~~~
+
+Consider the following limitations when performing aggregation operations:
+
+- Returned documents cannot violate the
+ :manual:`BSON document size limit `
+ of 16 megabytes.
+- Pipeline stages have a memory limit of 100 megabytes by default. You can exceed this
+ limit by creating an options array that sets the ``allowDiskUse`` option to ``true``
+ and passing the array to the ``MongoDB\Collection::aggregate()`` method.
+
+ .. important:: $graphLookup Exception
+
+ The :manual:`$graphLookup
+ ` stage has a strict
+ memory limit of 100 megabytes and ignores the ``allowDiskUse`` option.
+
+.. _php-aggregation-example:
+
+Aggregation Example
+-------------------
+
+.. note::
+
+ The examples in this guide use the ``restaurants`` collection in the ``sample_restaurants``
+ database from the :atlas:`Atlas sample datasets `. To learn how to create a
+ free MongoDB Atlas cluster and load the sample datasets, see the :atlas:`Get Started with Atlas
+ ` guide.
+
+To perform an aggregation, pass an array containing the pipeline stages to
+the ``MongoDB\Collection::aggregate()`` method.
+
+The following code example produces a count of the number of bakeries in each borough
+of New York. To do so, it uses an aggregation pipeline that contains the following stages:
+
+- :manual:`$match ` stage to filter for documents
+ in which the ``cuisine`` field contains the value ``'Bakery'``
+
+- :manual:`$group ` stage to group the matching
+ documents by the ``borough`` field, accumulating a count of documents for each distinct
+ value
+
+.. io-code-block::
+ :copyable:
+
+ .. input:: /includes/aggregation.php
+ :start-after: start-match-group
+ :end-before: end-match-group
+ :language: php
+ :dedent:
+
+ .. output::
+ :visible: false
+
+ {"_id":"Brooklyn","count":173}
+ {"_id":"Queens","count":204}
+ {"_id":"Bronx","count":71}
+ {"_id":"Staten Island","count":20}
+ {"_id":"Missing","count":2}
+ {"_id":"Manhattan","count":221}
+
+Explain an Aggregation
+~~~~~~~~~~~~~~~~~~~~~~
+
+To view information about how MongoDB executes your operation, you can
+instruct the MongoDB query planner to **explain** it. When MongoDB explains
+an operation, it returns **execution plans** and performance statistics.
+An execution plan is a potential way in which MongoDB can complete an operation.
+When you instruct MongoDB to explain an operation, it returns both the
+plan MongoDB executed and any rejected execution plans.
+
+To explain an aggregation operation, construct a ``MongoDB\Operation\Aggregate`` object
+and pass the database, collection, and pipeline stages as parameters. Then, pass the
+``MongoDB\Operation\Aggregate`` object to the ``MongoDB\Collection::explain()`` method.
+
+The following example instructs MongoDB to explain the aggregation operation
+from the preceding :ref:`php-aggregation-example`:
+
+.. io-code-block::
+ :copyable:
+
+ .. input:: /includes/aggregation.php
+ :start-after: start-explain
+ :end-before: end-explain
+ :language: php
+ :dedent:
+
+ .. output::
+ :visible: false
+
+ {"explainVersion":"2","queryPlanner":{"namespace":"sample_restaurants.restaurants",
+ "indexFilterSet":false,"parsedQuery":{"cuisine":{"$eq":"Bakery"}},"queryHash":"865F14C3",
+ "planCacheKey":"D56D6F10","optimizedPipeline":true,"maxIndexedOrSolutionsReached":false,
+ "maxIndexedAndSolutionsReached":false,"maxScansToExplodeReached":false,"winningPlan":{
+ ... }
+
+Additional Information
+----------------------
+
+To view a tutorial that uses the {+php-library+} to create complex aggregation
+pipelines, see `Complex Aggregation Pipelines with Vanilla PHP and MongoDB
+`__
+in the MongoDB Developer Center.
+
+MongoDB Server Manual
+~~~~~~~~~~~~~~~~~~~~~
+
+To learn more about the topics discussed in this guide, see the following
+pages in the {+mdb-server+} manual:
+
+- To view a full list of expression operators, see :manual:`Aggregation
+ Operators `.
+
+- To learn about assembling an aggregation pipeline and to view examples, see
+ :manual:`Aggregation Pipeline `.
+
+- To learn more about creating pipeline stages, see :manual:`Aggregation
+ Stages `.
+
+- To learn more about explaining MongoDB operations, see
+ :manual:`Explain Output ` and
+ :manual:`Query Plans `.
+
+.. TODO:
+ Aggregation Tutorials
+ ~~~~~~~~~~~~~~~~~~~~~
+
+.. To view step-by-step explanations of common aggregation tasks, see
+.. :ref:`php-aggregation-tutorials-landing`.
+
+API Documentation
+~~~~~~~~~~~~~~~~~
+
+To learn more about the methods discussed in this guide, see the
+following API documentation:
+
+- :phpmethod:`MongoDB\Collection::aggregate()`
+- :phpmethod:`MongoDB\Collection::explain()`
diff --git a/source/compatibility.txt b/source/compatibility.txt
new file mode 100644
index 00000000..acca9855
--- /dev/null
+++ b/source/compatibility.txt
@@ -0,0 +1,62 @@
+.. _php-compatibility:
+
+=============
+Compatibility
+=============
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: backwards compatibility, versions, upgrade
+
+MongoDB Compatibility
+---------------------
+
+The following compatibility table specifies the recommended version or versions
+of the {+php-library+} and extension that you can use with a specific version of MongoDB.
+
+The first column lists the version of the library and extension.
+
+.. sharedinclude:: dbx/lifecycle-schedule-callout.rst
+
+.. sharedinclude:: dbx/compatibility-table-legend.rst
+
+.. include:: /includes/mongodb-compatibility-table-php.rst
+
+For more information on how to read the compatibility tables, see our guide on
+:ref:`MongoDB Compatibility Tables `.
+
+Language Compatibility
+----------------------
+
+The following compatibility table specifies the recommended version or versions
+of the {+php-library+} and extension that you can use with a specific version of PHP.
+
+The first column lists the version of the library and extension.
+
+.. include:: /includes/language-compatibility-table-php.rst
+
+For more information on how to read the compatibility tables, see our guide on
+:ref:`MongoDB Compatibility Tables `.
+
+How to Get Help
+---------------
+
+If you have questions about compatibility, visit the following resources for further guidance:
+
+- Ask questions on our :community-forum:`MongoDB Community Forums <>`.
+- Visit our :technical-support:`Support Channels >`.
+- File an issue or feature request in our issue tracker, JIRA, under one of the
+ following projects:
+
+ - `PHPC - Extension `_
+
+ - `PHPLIB - Library `_
diff --git a/source/connect.txt b/source/connect.txt
new file mode 100644
index 00000000..7bbdce1e
--- /dev/null
+++ b/source/connect.txt
@@ -0,0 +1,416 @@
+.. _php-connect:
+
+==================
+Connect to MongoDB
+==================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :description: Learn how to use the PHP library to connect to MongoDB.
+ :keywords: client, ssl
+
+.. toctree::
+ :titlesonly:
+ :maxdepth: 1
+
+ /connect/client
+ /connect/connection-options
+ /connect/connection-targets
+ /connect/tls
+ /connect/stable-api
+
+Overview
+--------
+
+This page contains code examples that show how to connect your PHP application
+to MongoDB with various settings.
+
+.. tip::
+
+ To learn more about the connection options on this page, see the link
+ provided in each section.
+
+To use a connection example from this page, copy the code example into the
+:ref:`sample application ` or your own application.
+Make sure to replace all placeholders in the code examples, such as
+````, with the relevant values for your MongoDB deployment.
+
+.. _php-connect-sample:
+
+.. include:: /includes/usage-examples/sample-app-intro.rst
+
+.. literalinclude:: /includes/usage-examples/connect-sample-app.php
+ :language: php
+ :copyable: true
+ :linenos:
+ :emphasize-lines: 5-7
+
+.. important:: Percent-Encoding
+
+ You must :wikipedia:`percent-encode ` a username and password before
+ you include them in a MongoDB URI. You can use the ``rawurlencode()`` method to encode
+ these values according to the URI syntax specified in `RFC 3986 `__.
+ Don't percent-encode the username or password when passing them in an options array
+ parameter to the ``MongoDB\Client`` constructor.
+
+Connection
+----------
+
+Atlas
+~~~~~
+
+The following code shows how to connect to a MongoDB Atlas deployment:
+
+.. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-atlas
+ :end-before: end-atlas
+
+To learn more about connecting to an Atlas deployment, see :ref:`php-connection-atlas`
+in the Connection Targets guide.
+
+Local Deployment
+~~~~~~~~~~~~~~~~
+
+The following code shows how to connect to a local MongoDB deployment:
+
+.. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-local
+ :end-before: end-local
+
+.. note::
+
+ If you don't specify the ``$uri`` parameter, the connection URI defaults to
+ ``'mongodb://127.0.0.1:27017'``.
+
+To learn more about connecting to a local deployment, see :ref:`php-connection-local`
+in the Connection Targets guide.
+
+Replica Set
+~~~~~~~~~~~
+
+The following code shows how to connect to a replica set deployment:
+
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: Client
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-replica-set-client
+ :end-before: end-replica-set-client
+
+ .. tab:: Connection URI
+ :tabid: connectionstring
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-replica-set-uri
+ :end-before: end-replica-set-uri
+
+.. tip::
+
+ To maintain your connection to a replica set deployment when one
+ host is down, you can provide multiple replica set members in the
+ connection URI.
+
+To learn more about connecting to a replica set, see :ref:`php-connection-replica-set`
+in the Connection Targets guide.
+
+Transport Layer Security (TLS)
+------------------------------
+
+Enable TLS
+~~~~~~~~~~
+
+The following code shows how to enable TLS for the connection to your
+MongoDB instance:
+
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: Client
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-enable-tls-client
+ :end-before: end-enable-tls-client
+
+ .. tab:: Connection URI
+ :tabid: connectionstring
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-enable-tls-uri
+ :end-before: end-enable-tls-uri
+
+To learn more about enabling TLS, see :ref:`php-enable-tls` in
+the TLS Configuration guide.
+
+Specify a Certificate Authority (CA) File
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following code shows how to specify the path to your CA file
+for the connection to your MongoDB instance:
+
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: Client
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-ca-file-client
+ :end-before: end-ca-file-client
+
+ .. tab:: Connection URI
+ :tabid: connectionstring
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-ca-file-uri
+ :end-before: end-ca-file-uri
+
+To learn more about specifying a CA file, see :ref:`php-specify-ca-file` in
+the TLS Configuration guide.
+
+Disable OCSP Checks
+~~~~~~~~~~~~~~~~~~~
+
+The following code shows how to prevent the driver from contacting
+the OCSP endpoint:
+
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: Client
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-disable-ocsp-client
+ :end-before: end-disable-ocsp-client
+
+ .. tab:: Connection URI
+ :tabid: connectionstring
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-disable-ocsp-uri
+ :end-before: end-disable-ocsp-uri
+
+To learn more about disabling OCSP checks, see :ref:`php-disable-ocsp` in
+the TLS Configuration guide.
+
+Specify a Certificate Revocation List (CRL)
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following code shows how to instruct the driver to verify the server's
+certificate against a CRL:
+
+.. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-crl
+ :end-before: end-crl
+
+To learn more about specifying a CRL, see :ref:`php-crl` in the TLS
+configuration guide.
+
+Present a Client Certificate
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following code shows how to specify the client certificate that
+the driver presents to your MongoDB deployment:
+
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: Client
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-client-cert-client
+ :end-before: end-client-cert-client
+
+ .. tab:: Connection URI
+ :tabid: connectionstring
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-client-cert-uri
+ :end-before: end-client-cert-uri
+
+To learn more about specifying a client certificate, see :ref:`php-client-cert` in
+the TLS Configuration guide.
+
+Provide a Certificate Key File Password
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following code shows how to specify the password for your
+client certificate:
+
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: Client
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-key-file-client
+ :end-before: end-key-file-client
+
+ .. tab:: Connection URI
+ :tabid: connectionstring
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-key-file-uri
+ :end-before: end-key-file-uri
+
+.. important::
+
+ When replacing the ```` placeholder in the connection URI, ensure
+ that you :wikipedia:`percent-encode ` the value.
+
+To learn more about providing a key file password, see :ref:`php-key-file-password` in
+the TLS Configuration guide.
+
+Allow Insecure TLS
+~~~~~~~~~~~~~~~~~~
+
+The following code shows how to relax TLS constraints, which has the same
+effect as disabling both :ref:`certificate validation `
+and :ref:`hostname verification `:
+
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: Client
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-insecure-tls-client
+ :end-before: end-insecure-tls-client
+
+ .. tab:: Connection URI
+ :tabid: connectionstring
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-insecure-tls-uri
+ :end-before: end-insecure-tls-uri
+
+To learn more about allowing insecure TLS, see :ref:`php-insecure-tls` in
+the TLS Configuration guide.
+
+.. warning::
+
+ Setting the ``tlsInsecure`` option to ``true`` might expose your application
+ to security risks. Enabling this option makes your application insecure and
+ potentially vulnerable to expired certificates and to foreign processes posing
+ as valid client instances.
+
+.. _php-connect-disable-cert:
+
+Disable Certificate Validation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following code shows how to disable certificate validation:
+
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: Client
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-disable-cert-client
+ :end-before: end-disable-cert-client
+
+ .. tab:: Connection URI
+ :tabid: connectionstring
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-disable-cert-uri
+ :end-before: end-disable-cert-uri
+
+To learn more about disabling certificate validation, see :ref:`php-insecure-tls` in
+the TLS Configuration guide.
+
+.. _php-connect-disable-hostname:
+
+Disable Hostname Verification
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The following code shows how to disable hostname verification:
+
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: Client
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-disable-hostname-client
+ :end-before: end-disable-hostname-client
+
+ .. tab:: Connection URI
+ :tabid: connectionstring
+
+ .. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-disable-hostname-uri
+ :end-before: end-disable-hostname-uri
+
+To learn more about disabling hostname verification, see :ref:`php-insecure-tls` in
+the TLS Configuration guide.
+
+{+stable-api+}
+--------------
+
+The following code shows how to enable the {+stable-api+} for the
+connection to your MongoDB instance:
+
+.. literalinclude:: /includes/usage-examples/connect-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-stable-api
+ :end-before: end-stable-api
+
+To learn more about the {+stable-api+}, see the :ref:`php-stable-api` guide.
+
+.. TODO:
+ Network Compression
+ -------------------
\ No newline at end of file
diff --git a/source/connect/client.txt b/source/connect/client.txt
new file mode 100644
index 00000000..bef37b50
--- /dev/null
+++ b/source/connect/client.txt
@@ -0,0 +1,105 @@
+.. _php-client:
+
+=======================
+Create a MongoDB Client
+=======================
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: connection string, URI, server, Atlas, settings
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+Overview
+--------
+
+To connect to a MongoDB deployment, you must create the following items:
+
+- **Connection URI**, also known as a *connection string*, which tells the {+library-short+}
+ which MongoDB deployment to connect to.
+- **MongoDB\\Client** object, which creates the connection to the MongoDB deployment
+ and lets you perform operations on it.
+
+You can also set options within either or both of these components to
+customize the way that the {+library-short+} behaves
+while connected to MongoDB.
+
+This guide describes the components of a connection string and shows how to
+use a ``MongoDB\Client`` object to connect to a MongoDB deployment.
+
+.. _php-connection-uri:
+
+Connection URI
+--------------
+
+A standard connection string includes the following components:
+
+.. list-table::
+ :widths: 20 80
+ :header-rows: 1
+
+ * - Component
+ - Description
+
+ * - ``mongodb://``
+
+ - Required. A prefix that identifies this as a string in the
+ standard connection format.
+
+ * - ``db_username:db_password``
+
+ - Optional. Authentication credentials. If you include these, the client
+ authenticates the user against the database specified in ``authSource``.
+ For more information about the ``authSource`` connection option, see
+ :ref:`php-auth`.
+
+ * - ``host[:port]``
+
+ - Required. The host and optional port number where MongoDB is running. If you don't
+ include the port number, the driver uses the default port, ``27017``.
+
+ * - ``/defaultauthdb``
+
+ - Optional. The authentication database to use if the
+ connection string includes ``db_username:db_password@``
+ authentication credentials but not the ``authSource`` option. If you don't include
+ this component, the client authenticates the user against the ``admin`` database.
+
+ * - ``?``
+
+ - Optional. A query string that specifies connection-specific
+ options as ``=`` pairs. See
+ :ref:`php-connection-options` for a full description of
+ these options.
+
+To learn more about connection strings, see
+:manual:`Connection Strings ` in the
+Server manual.
+
+Create a MongoDB\Client
+-----------------------
+
+To create a connection to MongoDB, pass your connection string when constructing
+an instance of the ``MongoDB\Client`` class.
+
+In the following example, the library uses a sample connection URI to connect to a MongoDB
+deployment on port ``27017`` of ``localhost``:
+
+.. literalinclude:: /includes/connect/client.php
+ :language: php
+ :copyable: true
+
+API Documentation
+-----------------
+
+To learn more about creating a ``MongoDB\Client`` object in the {+library-short+},
+see the following API documentation:
+
+- :phpclass:`MongoDB\Client`
\ No newline at end of file
diff --git a/source/connect/connection-options.txt b/source/connect/connection-options.txt
new file mode 100644
index 00000000..8f123f94
--- /dev/null
+++ b/source/connect/connection-options.txt
@@ -0,0 +1,328 @@
+.. _php-connection-options:
+
+==========================
+Specify Connection Options
+==========================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: connection string, URI, server, Atlas, settings, configure
+
+Overview
+--------
+
+This page describes the MongoDB connection and authentication options
+available in the {+driver-short+}.
+
+Set Connection Options
+----------------------
+
+You can configure your connection by specifying options in the connection URI or by
+passing them to the ``MongoDB\Client`` constructor.
+
+.. _php-connection-uri:
+
+Using the Connection URI
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+If you pass a connection URI to the ``MongoDB\Client`` constructor, you can include
+connection options in the URI as ``=`` pairs. In the following example,
+the connection URI sets the ``tls`` option to ``true`` and the
+``tlsCertificateKeyFile`` option to ``/path/to/file.pem``:
+
+.. literalinclude:: /includes/connect/connection-options.php
+ :language: php
+ :copyable: true
+ :start-after: // start-connection-uri
+ :end-before: // end-connection-uri
+ :emphasize-lines: 2,5
+
+.. _php-client-object:
+
+Using a MongoDB\\Client Object
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+You can pass connection options to the ``MongoDB\Client`` constructor
+instead of including them in your connection URI.
+
+The following example shows how to use the ``$uriOptions`` parameter of the
+``MongoDB\Client`` constructor to set connection options:
+
+.. literalinclude:: /includes/connect/connection-options.php
+ :language: php
+ :copyable: true
+ :start-after: // start-client-options
+ :end-before: // end-client-options
+ :emphasize-lines: 5-8, 11
+
+.. note::
+
+ If you specify an option in both the ``$uriOptions`` parameter and in the connection
+ URI, the value in ``$uriOptions`` takes precedence.
+
+Connection URI Options
+----------------------
+
+The following sections describe the options that you can set for your connection to
+MongoDB. Each connection option links to its corresponding
+entry in the {+mdb-server+} manual.
+
+.. important:: Percent-Encoding
+
+ If the value of a connection option contains special characters, you must
+ :wikipedia:`percent-encode ` the value before including it
+ in the connection URI. You can use the ``rawurlencode()`` method to encode
+ these values according to the URI syntax specified in RFC 3986.
+
+ Don't percent-encode connection options when including them in the
+ ``$uriOptions`` parameter.
+
+ To learn more, see the following resources:
+
+ - `RFC 3986 `__
+ - :php:`rawurlencode ` in the PHP manual
+
+Replica Set Options
+~~~~~~~~~~~~~~~~~~~
+
+.. list-table::
+ :header-rows: 1
+ :stub-columns: 1
+
+ * - Connection Option
+ - Description
+
+ * - :manual:`directConnection `
+ - | **Data Type**: {+bool-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['directConnection' => true];``
+ | **Connection URI Example**: ``directConnection=true``
+
+ * - :manual:`replicaSet `
+ - | **Data Type**: {+string-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['replicaSet' => 'replicaSetName'];``
+ | **Connection URI Example**: ``replicaSet=replicaSetName``
+
+Connection Options
+~~~~~~~~~~~~~~~~~~
+
+TLS Options
+```````````
+To learn about the TLS options available in the {+driver-short+}, see the
+:ref:`TLS ` page.
+
+Timeout Options
+```````````````
+
+.. list-table::
+ :header-rows: 1
+ :stub-columns: 1
+
+ * - Connection Option
+ - Description
+
+ * - :manual:`connectTimeoutMS `
+ - | **Data Type**: {+int-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['connectTimeoutMS' => 2000];``
+ | **Connection URI Example**: ``connectTimeoutMS=2000``
+
+ * - :manual:`socketTimeoutMS `
+ - | **Data Type**: {+int-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['socketTimeoutMS' => 20000];``
+ | **Connection URI Example**: ``socketTimeoutMS=20000``
+
+.. _php-compression-options:
+
+Compression Options
+```````````````````
+
+.. list-table::
+ :header-rows: 1
+ :stub-columns: 1
+
+ * - Connection Option
+ - Description
+
+ * - :manual:`compressors `
+ - | **Data Type**: {+string-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['compressors' => 'snappy,zstd,zlib'];``
+ | **Connection URI Example**: ``compressors=snappy,zstd,zlib``
+
+ * - :manual:`zlibCompressionLevel `
+ - | **Data Type**: {+int-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['zlibCompressionLevel' => 3];``
+ | **Connection URI Example**: ``zlibCompressionLevel=3``
+
+Write Concern Options
+~~~~~~~~~~~~~~~~~~~~~
+
+.. list-table::
+ :header-rows: 1
+ :stub-columns: 1
+
+ * - Connection Option
+ - Description
+
+ * - :manual:`w `
+ - | **Data Type**: {+string-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['w' => 'majority'];``
+ | **Connection URI Example**: ``w=majority``
+
+ * - :manual:`wTimeoutMS `
+ - | **Data Type**: {+int-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['wTimeoutMS' => 10000];``
+ | **Connection URI Example**: ``wTimeoutMS=10000``
+
+ * - :manual:`journal `
+ - | **Data Type**: {+bool-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['journal' => true];``
+ | **Connection URI Example**: ``journal=true``
+
+Read Concern Options
+~~~~~~~~~~~~~~~~~~~~
+
+.. list-table::
+ :header-rows: 1
+ :stub-columns: 1
+
+ * - Connection Option
+ - Description
+
+ * - :manual:`readConcernLevel `
+ - | **Data Type**: {+string-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['readConcernLevel' => 'majority'];``
+ | **Connection URI Example**: ``readConcernLevel=majority``
+
+Read Preference Options
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. list-table::
+ :header-rows: 1
+ :stub-columns: 1
+ :widths: 22 78
+
+ * - Connection Option
+ - Description
+
+ * - :manual:`readPreference `
+ - | **Data Type**: :php:`MongoDB\Driver\ReadPreference `
+ | **MongoDB\\Client Example**: ``$uriOptions = ['readPreference' => 'secondaryPreferred'];``
+ | **Connection URI Example**: ``readPreference=secondaryPreferred``
+
+ * - :manual:`maxStalenessSeconds `
+ - | **Data Type**: {+int-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['maxStalenessSeconds' => 30];``
+ | **Connection URI Example**: ``maxStalenessSeconds=30``
+
+ * - :manual:`readPreferenceTags `
+ - | **Data Type**: ``array``
+ | **MongoDB\\Client Example**:
+
+ .. code-block:: php
+
+ $uriOptions = [
+ 'readPreferenceTags' => [
+ ['dc' => 'ny', 'rack' => 'r1'],
+ [],
+ ],
+ ];
+
+ **Connection URI Example**: ``readPreferenceTags=dc:ny,rack:r1&readPreferenceTags=``
+
+Authentication Options
+~~~~~~~~~~~~~~~~~~~~~~
+
+To learn about the authentication options available in the {+driver-short+}, see
+:ref:`Authentication Mechanisms. `
+
+Server Selection and Discovery Options
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. list-table::
+ :header-rows: 1
+ :stub-columns: 1
+ :widths: 30 70
+
+ * - Connection Option
+ - Description
+
+ * - :manual:`localThresholdMS `
+ - | **Data Type**: {+int-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['localThresholdMS' => 20];``
+ | **Connection URI Example**: ``localThresholdMS=20``
+
+ * - :manual:`serverSelectionTimeoutMS `
+ - | **Data Type**: {+int-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['serverSelectionTimeoutMS' => 5000];``
+ | **Connection URI Example**: ``serverSelectionTimeoutMS=5000``
+
+ * - :manual:`serverSelectionTryOnce `
+ - | **Data Type**: {+bool-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['serverSelectionTryOnce' => false];``
+ | **Connection URI Example**: ``serverSelectionTryOnce=false``
+
+ * - :manual:`heartbeatFrequencyMS `
+ - | **Data Type**: {+int-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['heartbeatFrequencyMS' => 30000];``
+ | **Connection URI Example**: ``heartbeatFrequencyMS=30000``
+
+ * - :manual:`socketCheckIntervalMS `
+ - | **Data Type**: {+int-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['socketCheckIntervalMS' => 4000];``
+ | **Connection URI Example**: ``socketCheckIntervalMS=4000``
+
+Miscellaneous Configuration
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. list-table::
+ :header-rows: 1
+ :stub-columns: 1
+
+ * - Connection Option
+ - Description
+
+ * - :manual:`appName `
+ - | **Data Type**: {+string-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['appName' => 'myApp'];``
+ | **Connection URI Example**: ``appName=myApp``
+
+ * - :manual:`retryReads `
+ - | **Data Type**: {+bool-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['retryReads' => false];``
+ | **Connection URI Example**: ``retryReads=false``
+
+ * - :manual:`retryWrites `
+ - | **Data Type**: {+bool-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['retryWrites' => false];``
+ | **Connection URI Example**: ``retryWrites=false``
+
+ * - :manual:`loadBalanced `
+ - | **Data Type**: {+bool-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['loadBalanced' => true];``
+ | **Connection URI Example**: ``loadBalanced=true``
+
+ * - :manual:`srvMaxHosts `
+ - | **Data Type**: {+int-data-type+}
+ | **MongoDB\\Client Example**: ``$uriOptions = ['srvMaxHosts' => 5];``
+ | **Connection URI Example**: ``srvMaxHosts=5``
+
+API Documentation
+-----------------
+
+For more information about the ``MongoDB\Client`` class, see the following {+driver-short+}
+API documentation:
+
+- :phpclass:`MongoDB\Client`
+
+For more information about the ``MongoDB\Driver\ReadPreference`` class, see the following
+{+extension-short+} API documentation:
+
+- :php:`MongoDB\Driver\ReadPreference `
\ No newline at end of file
diff --git a/source/connect/connection-targets.txt b/source/connect/connection-targets.txt
new file mode 100644
index 00000000..59497bb0
--- /dev/null
+++ b/source/connect/connection-targets.txt
@@ -0,0 +1,116 @@
+.. _php-connection-targets:
+
+==========================
+Choose a Connection Target
+==========================
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: connection string, URI, server, settings, client, stable api
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+Overview
+--------
+
+In this guide, you can learn how to use a connection string and ``MongoDB\Client`` object
+to connect to different types of MongoDB deployments.
+
+.. _php-connection-atlas:
+
+Atlas
+-----
+
+To connect to a MongoDB deployment on Atlas, include the following elements
+in your connection string:
+
+- URI of your Atlas cluster
+- Database username
+- Database user's password
+
+Then, pass your connection string to the ``MongoDB\Client`` constructor.
+
+When you connect to Atlas, we recommend using the {+stable-api+} client option to avoid
+breaking changes when Atlas upgrades to a new version of {+mdb-server+}.
+To learn more about the {+stable-api+} feature, see the :ref:`{+stable-api+} page
+`.
+
+The following code shows how to use the {+library-short+} to connect to an Atlas cluster.
+The code also uses the ``serverApi`` option to specify a {+stable-api+} version.
+
+.. literalinclude:: /includes/connect/atlas.php
+ :copyable: true
+ :language: php
+
+.. tip::
+
+ Follow the :ref:`php-connection-string` step of the Quick Start
+ to retrieve your connection string.
+
+.. _php-connection-local:
+
+Local Deployments
+-----------------
+
+To connect to a local MongoDB deployment, use ``localhost`` as the hostname. By
+default, the ``mongod`` process runs on port 27017, though you can customize this for
+your deployment.
+
+The following code shows how to use the {+library-short+} to connect to a local MongoDB
+deployment:
+
+.. literalinclude:: /includes/connect/client.php
+ :language: php
+ :copyable: true
+
+.. _php-connection-replica-set:
+
+Replica Sets
+------------
+
+To connect to a replica set, specify the hostnames (or IP addresses) and
+port numbers of the replica set members in your connection string.
+
+If you aren't able to provide a full list of hosts in the replica set, you can
+specify one or more of the hosts in the replica set and instruct the {+library-short+} to
+perform automatic discovery to find the others. To instruct the driver to perform
+automatic discovery, choose one of the following actions:
+
+- Specify the name of the replica set as the value of the ``replicaSet`` parameter.
+- Specify ``false`` as the value of the ``directConnection`` parameter.
+- Specify more than one host in the replica set.
+
+In the following example, the driver uses a sample connection URI to connect to the
+MongoDB replica set ``sampleRS``, which is running on port ``27017`` of three different
+hosts, including ``host1``:
+
+.. literalinclude:: /includes/connect/replica-set.php
+ :language: php
+ :copyable: true
+
+Initialization
+~~~~~~~~~~~~~~
+
+To initialize a replica set, you must connect directly to a single member. To do so,
+set the ``directConnection`` connection
+option to ``true`` in the connection string. The following code example shows how to
+set this connection option:
+
+.. literalinclude:: /includes/connect/direct-connection.php
+ :language: php
+ :copyable: true
+
+API Documentation
+-----------------
+
+To learn more about using the ``MongoDB\Client`` class,
+see the following API documentation:
+
+- :phpclass:`MongoDB\Client`
\ No newline at end of file
diff --git a/source/connect/stable-api.txt b/source/connect/stable-api.txt
new file mode 100644
index 00000000..e00eeb55
--- /dev/null
+++ b/source/connect/stable-api.txt
@@ -0,0 +1,119 @@
+.. _php-stable-api:
+
+==============
+{+stable-api+}
+==============
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: compatible, backwards, upgrade
+
+.. note::
+
+ The {+stable-api+} feature requires {+mdb-server+} 5.0 or later.
+
+Overview
+--------
+
+In this guide, you can learn how to specify **{+stable-api+}** compatibility when
+connecting to a MongoDB deployment.
+
+The {+stable-api+} feature forces the server to run operations with behaviors compatible
+with the API version you specify. When you update either your library or server version,
+the API version changes, which can change the way these operations behave.
+Using the {+stable-api+} ensures consistent responses from the server and
+provides long-term API stability for your application.
+
+The following sections describe how you can enable and customize {+stable-api+} for
+your MongoDB client. For more information about the {+stable-api+}, including a list of
+the commands it supports, see :manual:`Stable API ` in the
+{+mdb-server+} manual.
+
+Enable the {+stable-api+}
+-------------------------
+
+To enable the {+stable-api+}, perform the following steps:
+
+1. Construct a ``MongoDB\Driver\ServerApi`` object and pass the {+stable-api+}
+ version you want to use. Currently, the library supports only version 1.
+#. Construct a ``MongoDB\Client`` object. For the ``driverOptions`` parameter, pass an
+ array that contains the ``serverApi`` option. Set this option to the
+ ``MongoDB\Driver\ServerApi`` object you created in the previous step.
+
+The following code example shows how to specify {+stable-api+} version 1:
+
+.. literalinclude:: /includes/connect/stable-api.php
+ :language: php
+ :copyable: true
+ :start-after: // start-specify-v1
+ :end-before: // end-specify-v1
+ :emphasize-lines: 3-4
+
+.. note::
+
+ After you create a ``MongoDB\Client`` instance with
+ a specified API version, all commands you run with the client use the specified
+ version. If you need to run commands using more than one version of the
+ {+stable-api+}, create a new ``MongoDB\Client`` instance.
+
+.. _stable-api-options:
+
+Configure the {+stable-api+}
+------------------------
+
+The ``MongoDB\Driver\ServerApi`` constructor also accepts the following optional parameters.
+You can use these parameters to customize the behavior of the {+stable-api+}.
+
+.. list-table::
+ :header-rows: 1
+ :stub-columns: 1
+ :widths: 25,75
+
+ * - Parameter
+ - Description
+
+ * - strict
+ - | **Optional**. When ``true``, if you call a command that isn't part of
+ the declared API version, the server raises an exception.
+ |
+ | Default: ``null``. If this parameter is null, the server applies its default
+ value of ``false``.
+
+ * - deprecationErrors
+ - | **Optional**. When ``true``, if you call a command that is deprecated in the
+ declared API version, the server raises an exception.
+ |
+ | Default: ``null``. If this parameter is null, the server applies its default
+ value of ``false``.
+
+The following code example shows how you can use these parameters when constructing a
+``MongoDB\Driver\ServerApi`` object:
+
+.. literalinclude:: /includes/connect/stable-api.php
+ :language: php
+ :copyable: true
+ :start-after: // start-stable-api-options
+ :end-before: // end-stable-api-options
+ :emphasize-lines: 3-4
+
+API Documentation
+-----------------
+
+For more information about the ``MongoDB\Client`` class, see the following {+library-short+}
+API documentation:
+
+- :phpclass:`MongoDB\Client`
+
+For more information about the ``MongoDB\Driver\ServerApi`` class, see the following
+{+extension-short+} API documentation:
+
+- :php:`MongoDB\Driver\ServerApi `
\ No newline at end of file
diff --git a/source/connect/tls.txt b/source/connect/tls.txt
new file mode 100644
index 00000000..e8051122
--- /dev/null
+++ b/source/connect/tls.txt
@@ -0,0 +1,268 @@
+.. _php-tls:
+
+========================================
+Configure Transport Layer Security (TLS)
+========================================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: security, authentication, transport layer security, encrypt
+
+Overview
+--------
+
+In this guide, you can learn how to use the :wikipedia:`TLS `
+protocol to secure your connection to a MongoDB deployment.
+
+When you enable TLS for a connection, the {+library-short+} performs the following actions:
+
+- Uses TLS to connect to the MongoDB deployment
+- Verifies the deployment's certificate
+- Ensures that the certificate certifies the deployment
+
+To learn how to configure your MongoDB deployment for TLS, see the
+:manual:`TLS configuration guide ` in the
+{+mdb-server+} manual.
+
+.. note::
+
+ This page assumes prior knowledge of TLS/SSL and access to valid certificates.
+ A full description of TLS/SSL, PKI (Public Key Infrastructure) certificates, and
+ Certificate Authorities (CAs) is beyond the scope of this documentation.
+
+.. tip::
+
+ The {+library-short+} delegates most TLS behavior to the MongoDB C Driver.
+ For information about how the C driver handles TLS, including configuration steps
+ and expected behavior, see
+ `Configuring TLS `__
+ in the C driver Documentation.
+
+.. _php-enable-tls:
+
+Enable TLS
+----------
+
+To enable TLS for the connection to your MongoDB deployment, set the ``tls`` connection
+option to ``true``. You can do this in two ways: by using the ``uriOptions`` parameter
+of the ``MongoDB\Client`` constructor or through a parameter in your connection string.
+
+.. include:: /includes/connect/tls-tabs.rst
+
+.. tip::
+
+ If your connection string includes the ``+srv`` modification, which specifies the
+ SRV connection format, TLS is enabled on your connection by default.
+
+ To learn more about the SRV connection format, see
+ :manual:`SRV Connection Format `
+ in the {+mdb-server+} documentation.
+
+.. _php-specify-ca-file:
+
+Specify a CA File
+------------------
+
+During the TLS handshake, the MongoDB deployment presents a certificate key file to your
+application to establish its identity. Usually, a deployment's certificate has been
+signed by a well-known CA (certificate authority), and your application relies on this CA
+to validate the certificate.
+
+During testing, however, you might want to act as your own CA.
+In this case, you must instruct the {+library-short+} to
+use your CA certificates instead of ones signed by another CA.
+
+To do so, use the ``tlsCAFile`` connection option to specify the path to a ``.pem`` file
+containing the root certificate chain.
+You can do this in two ways: by using the ``uriOptions`` parameter
+of the ``MongoDB\Client`` constructor or through a parameter in your connection string.
+
+.. include:: /includes/connect/ca-file-tabs.rst
+
+.. _php-specify-ca-directory:
+
+Specify a CA Directory
+~~~~~~~~~~~~~~~~~~~~~~
+
+If you are using OpenSSL or LibreSSL (``libtls``) for TLS support, you can also use
+the ``ca_dir`` option to instruct
+the {+library-short+} to search for a CA file within a directory. The driver searches this
+directory if it doesn't find a CA file at the path specified in the ``tlsCAFile`` option.
+
+The following code example shows how to use the ``driverOptions`` parameter to specify the
+``ca_dir`` option:
+
+.. literalinclude:: /includes/connect/ca-dir.php
+ :language: php
+ :copyable: true
+
+.. tip::
+
+ This option corresponds to the OpenSSL
+ `SSL_CTX_load_verify_locations `__
+ parameter and
+ the LibreSSL `tls_config_set_ca_path `__
+ parameter.
+
+.. _php-certificate-revocation:
+
+Check Certificate Revocation
+----------------------------
+
+When an X.509 certificate is no longer trustworthy—for example, if its private key
+has been compromised—the CA revokes the certificate. The {+library-short+} includes two ways
+to check whether a server's certificate has been revoked.
+
+.. _php-disable-ocsp:
+
+OCSP
+~~~~
+
+The Online Certificate Status Protocol (OCSP) process varies depending on the version of
+{+mdb-server+} you're connecting to:
+
+- **MongoDB v4.4 or later:** The server staples a
+ time-stamped OCSP response to its certificate. The {+library-short+} validates the certificate
+ against the OCSP response. If the CA has revoked the certificate, or if the OCSP response
+ is otherwise invalid, the TLS handshake fails.
+- **MongoDB v4.3 or earlier:** The server supplies an OCSP endpoint, which the {+library-short+}
+ contacts directly. The {+library-short+} then validates the certificate against the OCSP
+ response. If the CA hasn't revoked the certificate, the TLS handshake continues, even if
+ the OCSP response is invalid or malformed.
+
+To stop the {+library-short+} from contacting the OCSP endpoint, set the
+``tlsDisableOCSPEndpointCheck`` connection option to ``true``.
+You can do this in two ways: by passing an argument to the
+``MongoDB\Client`` constructor or through a parameter in your connection string.
+
+.. include:: /includes/connect/ocsp-tabs.rst
+
+.. note::
+
+ Even if the ``tlsDisableOCSPEndpointCheck`` option is set to ``true``, the {+library-short+}
+ still verifies any OCSP response stapled to a server's certificate.
+
+.. _php-crl:
+
+Certificate Revocation List
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Instead of using OCSP, you can use the instruct the {+library-short+}
+to check the server's certificate
+against a Certificate Revocation List (CRL) published by the CA. To do so, set the
+``crl_file`` option to the file path of the CRL. Include this option in the
+``driverOptions`` parameter of the ``MongoDB\Client`` constructor, as shown
+in the following code example:
+
+.. literalinclude:: /includes/connect/crl-file.php
+ :language: php
+ :copyable: true
+
+.. tip::
+
+ You can specify a CRL file in either the ``.pem`` or ``.der`` format.
+
+.. _php-client-cert:
+
+Present a Client Certificate
+----------------------------
+
+Some MongoDB deployments require every connecting application to present a client certificate
+that proves its identity. To specify the client certificate for the {+library-short+} to
+present, set the ``tleCertificateKeyFile`` option to the file path of the ``.pem`` file that
+contains your certificate and private key.
+
+You can do this in two ways: by using the ``uriOptions`` parameter
+of the ``MongoDB\Client`` constructor or through a parameter in your connection string.
+
+.. include:: /includes/connect/client-cert-tabs.rst
+
+.. important::
+
+ Your client certificate and private key must be in the same ``.pem`` file. If they
+ are stored in different files, you must concatenate them. The following example
+ shows how to concatenate a key file and a certificate file into a third file called
+ ``combined.pem`` on a Unix system:
+
+ .. code-block:: sh
+
+ $ cat key.pem cert.pem > combined.pem
+
+.. _php-key-file-password:
+
+Provide a Key Password
+~~~~~~~~~~~~~~~~~~~~~~
+
+If the private key in your certificate file is encrypted, you must use the
+``tlsCertificateKeyFilePassword`` option to provide the password.
+You can do this in two ways: by using the ``uriOptions`` parameter
+of the ``MongoDB\Client`` constructor or through a parameter in your connection string.
+
+.. include:: /includes/connect/key-file-password.rst
+
+.. _php-insecure-tls:
+
+Allow Insecure TLS
+------------------
+
+When TLS is enabled, the {+library-short+} automatically verifies the certificate that
+the server presents. When testing your code, you can disable this verification.
+This is known as *insecure TLS.*
+
+When insecure TLS is enabled, the driver requires only that the server present an
+X.509 certificate. The driver accepts a certificate even if any of the following are
+true:
+
+- The hostname of the server and the subject name (or subject alternative name)
+ on the certificate don't match.
+- The certificate is expired or not yet valid.
+- The certificate doesn't have a trusted root certificate in the chain.
+- The certificate purpose isn't valid for server identification.
+
+.. note::
+
+ Even when insecure TLS is enabled, communication between the client and server
+ is encrypted with TLS.
+
+To enable insecure TLS, set the ``tlsInsecure`` connection
+option to ``true``. You can do this in two ways: by passing an argument to the
+``MongoDB\Client`` constructor or through a parameter in your connection string.
+
+.. include:: /includes/connect/insecure-tls-tabs.rst
+
+To disable only certificate validation, set the ``tlsAllowInvalidCertificates`` option to
+``true``, and set the ``tlsInsecure`` option to ``false`` or omit it:
+
+.. include:: /includes/connect/disable-cert-validation-tabs.rst
+
+To disable only hostname verification, set the ``tlsAllowInvalidHostnames`` option to
+``true``, and set the ``tlsInsecure`` option to ``false`` or omit it:
+
+.. include:: /includes/connect/disable-host-verification-tabs.rst
+
+.. warning:: Don't Use in Production
+
+ Always set the ``tlsInsecure``, ``tlsAllowInvalidCertificates``, and
+ ``tlsAllowInvalidHostnames`` options to ``false`` in production.
+
+ Setting any of these options to ``true`` in a production environment makes
+ your application insecure and potentially
+ vulnerable to expired certificates and to foreign processes posing
+ as valid client instances.
+
+API Documentation
+-----------------
+
+To learn more about configuring TLS for the {+library-short+},
+see the following API documentation:
+
+- :phpclass:`MongoDB\Client`
\ No newline at end of file
diff --git a/source/data-formats.txt b/source/data-formats.txt
new file mode 100644
index 00000000..ca4e482a
--- /dev/null
+++ b/source/data-formats.txt
@@ -0,0 +1,40 @@
+.. _php-data-formats:
+
+========================
+Specialized Data Formats
+========================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 1
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: store, bson, codec
+
+.. toctree::
+ :titlesonly:
+ :maxdepth: 1
+
+ /data-formats/custom-types
+ /data-formats/codecs
+ /data-formats/decimal128
+ /data-formats/modeling-bson-data
+
+
+Overview
+--------
+
+You can use several types of specialized data formats in your {+library-short+}
+application. To learn how to work with these data formats, see the following
+guides:
+
+- :ref:`php-custom-types`
+- :ref:`php-codecs`
+- :ref:`php-decimal128`
+- :ref:`php-bson`
\ No newline at end of file
diff --git a/source/tutorial/codecs.txt b/source/data-formats/codecs.txt
similarity index 99%
rename from source/tutorial/codecs.txt
rename to source/data-formats/codecs.txt
index a4bb5dd6..44a6f41f 100644
--- a/source/tutorial/codecs.txt
+++ b/source/data-formats/codecs.txt
@@ -1,3 +1,5 @@
+.. _php-codecs:
+
======
Codecs
======
diff --git a/source/tutorial/custom-types.txt b/source/data-formats/custom-types.txt
similarity index 99%
rename from source/tutorial/custom-types.txt
rename to source/data-formats/custom-types.txt
index 243d7e52..f6cb7fb9 100644
--- a/source/tutorial/custom-types.txt
+++ b/source/data-formats/custom-types.txt
@@ -1,3 +1,5 @@
+.. _php-custom-types:
+
=================
Custom Data-Types
=================
diff --git a/source/tutorial/decimal128.txt b/source/data-formats/decimal128.txt
similarity index 99%
rename from source/tutorial/decimal128.txt
rename to source/data-formats/decimal128.txt
index 2397ccd8..523b6ac8 100644
--- a/source/tutorial/decimal128.txt
+++ b/source/data-formats/decimal128.txt
@@ -1,3 +1,5 @@
+.. _php-decimal128:
+
==========
Decimal128
==========
diff --git a/source/tutorial/modeling-bson-data.txt b/source/data-formats/modeling-bson-data.txt
similarity index 99%
rename from source/tutorial/modeling-bson-data.txt
rename to source/data-formats/modeling-bson-data.txt
index 5429b031..12424275 100644
--- a/source/tutorial/modeling-bson-data.txt
+++ b/source/data-formats/modeling-bson-data.txt
@@ -1,3 +1,5 @@
+.. _php-bson:
+
==================
Modeling BSON Data
==================
diff --git a/source/databases-collections.txt b/source/databases-collections.txt
new file mode 100644
index 00000000..43e2786f
--- /dev/null
+++ b/source/databases-collections.txt
@@ -0,0 +1,220 @@
+.. _php-databases-collections:
+
+=========================
+Databases and Collections
+=========================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: table, row, organize, storage, code example
+
+.. toctree::
+ :titlesonly:
+ :maxdepth: 1
+
+ /databases-collections/time-series
+
+Overview
+--------
+
+In this guide, you can learn how to use MongoDB databases and
+collections with the {+php-library+}.
+
+MongoDB organizes data into a hierarchy of the following levels:
+
+- **Databases**: Top-level data structures in a MongoDB deployment that store collections.
+- **Collections**: Groups of MongoDB documents. They are analogous to tables in relational databases.
+- **Documents**: Units that store literal data such as string, numbers, dates, and other embedded documents.
+ For more information about document field types and structure, see the
+ :manual:`Documents ` guide in the {+mdb-server+} manual.
+
+Access a Database
+-----------------
+
+Access a database by passing the database name to the ``MongoDB\Client::selectDatabase()``
+method.
+
+The following example accesses a database named ``test_database``:
+
+.. literalinclude:: /includes/databases-collections/databases-collections.php
+ :language: php
+ :dedent:
+ :start-after: start-access-database
+ :end-before: end-access-database
+
+Alternatively, you can implicitly call the ``MongoDB\Client::__get()`` magic method on
+a client object. This method allows you to select a database by using the syntax for
+accessing a class property. The following example uses this shorthand syntax to access
+the ``test_database`` database:
+
+.. literalinclude:: /includes/databases-collections/databases-collections.php
+ :language: php
+ :dedent:
+ :start-after: start-access-database-short
+ :end-before: end-access-database-short
+
+.. tip::
+
+ To learn more about ``__get()`` and PHP magic methods, see the following resources:
+
+ - :phpmethod:`MongoDB\Client::__get()` in the library API documentation
+ - :php:`Magic Methods ` in the PHP manual
+
+.. _php-db-coll-access-collection:
+
+Access a Collection
+-------------------
+
+Access a collection by using either of the following methods:
+
+- ``MongoDB\Client::selectCollection()``: Pass the database and collection names as
+ parameters
+- ``MongoDB\Database::selectCollection()``: Pass the collection name as a parameter
+
+The following example accesses a collection named ``test_collection`` by using the
+``MongoDB\Database::selectCollection()`` method:
+
+.. literalinclude:: /includes/databases-collections/databases-collections.php
+ :language: php
+ :dedent:
+ :start-after: start-access-collection
+ :end-before: end-access-collection
+
+.. tip::
+
+ If the provided collection name does not already exist in the database,
+ MongoDB implicitly creates the collection when you first insert data
+ into it.
+
+Alternatively, you can implicitly call the ``MongoDB\Database::__get()`` magic method on
+a database object. This method allows you to select a collection by using the syntax for
+accessing a class property. The following example uses this shorthand syntax to access
+the ``test_collection`` collection:
+
+.. literalinclude:: /includes/databases-collections/databases-collections.php
+ :language: php
+ :dedent:
+ :start-after: start-access-collection-short
+ :end-before: end-access-collection-short
+
+To learn more, see the :phpmethod:`MongoDB\Database::__get()`
+API documentation.
+
+.. _php-db-coll-create-collection:
+
+Create a Collection
+-------------------
+
+Pass a collection name to the ``MongoDB\Database::createCollection()`` method to
+explicitly create a collection in a MongoDB database.
+
+The following example creates a collection named ``example_collection``:
+
+.. literalinclude:: /includes/databases-collections/databases-collections.php
+ :language: php
+ :dedent:
+ :start-after: start-create-collection
+ :end-before: end-create-collection
+
+You can specify collection options, such as maximum size and document
+validation rules, by passing them as an array to the ``createCollection()`` method.
+For a full list of optional parameters, see the `API documentation
+<{+api+}/method/MongoDBDatabase-createCollection/#parameters>`__.
+
+Get a List of Collections
+-------------------------
+
+You can query for a list of collections in a database by calling the
+``MongoDB\Database::listCollections()`` method. The method returns a
+cursor containing all collections in the database and their associated metadata.
+
+The following example calls the ``listCollections()`` method and iterates over
+the returned iterator to print the collections from the :ref:`php-db-coll-access-collection`
+and :ref:`php-db-coll-create-collection` examples:
+
+.. io-code-block::
+ :copyable:
+
+ .. input:: /includes/databases-collections/databases-collections.php
+ :language: php
+ :start-after: start-find-collections
+ :end-before: end-find-collections
+ :dedent:
+
+ .. output::
+ :language: console
+ :visible: false
+
+ MongoDB\Model\CollectionInfo Object
+ (
+ [name] => example_collection
+ [type] => collection
+ ...
+ )
+ MongoDB\Model\CollectionInfo Object
+ (
+ [name] => test_collection
+ [type] => collection
+ ...
+ )
+
+Delete a Collection
+-------------------
+
+You can delete a collection from the database by using the ``MongoDB\Database::dropCollection()``
+method.
+
+The following example deletes the ``test_collection`` collection:
+
+.. literalinclude:: /includes/databases-collections/databases-collections.php
+ :language: php
+ :dedent:
+ :start-after: start-drop-collection
+ :end-before: end-drop-collection
+
+.. warning:: Dropping a Collection Deletes All Data in the Collection
+
+ Dropping a collection from your database permanently deletes all
+ documents and all indexes within that collection.
+
+ Drop a collection only if you no longer need the data in it.
+
+.. _php-config-read-write:
+
+Configure Read and Write Operations
+-----------------------------------
+
+You can control how read and write operations run on replica sets
+by specifying a read preference, read concern, or write concern.
+
+By default, databases inherit read and write settings from the ``MongoDB\Client``
+instance. Collections inherit these settings from the ``MongoDB\Client`` or
+``MongoDB\Database`` instance on which the ``selectCollection()`` method is called.
+You can change these settings by passing an options array to the
+``MongoDB\Client::selectDatabase()``, ``MongoDB\Client::selectCollection()``, or
+``MongoDB\Database::selectCollection()`` methods.
+
+To learn more about setting a read preference, read concern, and write concern,
+see the :ref:`php-read-write-pref` guide.
+
+API Documentation
+-----------------
+
+To learn more about any of the methods or types discussed in this
+guide, see the following API documentation:
+
+- :phpmethod:`MongoDB\Client::selectDatabase()`
+- :phpmethod:`MongoDB\Client::selectCollection()`
+- :phpmethod:`MongoDB\Database::selectCollection()`
+- :phpmethod:`MongoDB\Database::createCollection()`
+- :phpmethod:`MongoDB\Database::listCollections()`
+- :phpmethod:`MongoDB\Database::dropCollection()`
diff --git a/source/databases-collections/time-series.txt b/source/databases-collections/time-series.txt
new file mode 100644
index 00000000..9c21e2e3
--- /dev/null
+++ b/source/databases-collections/time-series.txt
@@ -0,0 +1,213 @@
+.. _php-time-series:
+
+=======================
+Time Series Collections
+=======================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 1
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: chronological, data format, code example
+
+Overview
+--------
+
+In this guide, you can learn how to use the {+php-library+} to create
+and interact with **time series collections**. These collections store
+time series data, which is composed of the following components:
+
+- Measured quantity
+- Timestamp for the measurement
+- Metadata that describes the measurement
+
+The following table describes sample situations for which you can store time
+series data:
+
+.. list-table::
+ :widths: 33, 33, 33
+ :header-rows: 1
+ :stub-columns: 1
+
+ * - Situation
+ - Measured Quantity
+ - Metadata
+
+ * - Recording monthly sales by industry
+ - Revenue in USD
+ - Company, country
+
+ * - Tracking weather changes
+ - Precipitation level
+ - Location, sensor type
+
+ * - Recording fluctuations in housing prices
+ - Monthly rent price
+ - Location, currency
+
+.. _php-time-series-create:
+
+Create a Time Series Collection
+-------------------------------
+
+.. important:: Server Version for Time Series Collections
+
+ To create and interact with time series collections, you must be
+ connected to a deployment running {+mdb-server+} 5.0 or later.
+
+You can create a time series collection to store time series data.
+To create a time series collection, pass an options array to the
+``MongoDB\Database::createCollection()`` method that sets the
+``timeseries`` option. When setting this option, include the following fields:
+
+- ``timeField``: Specifies the field that stores a timestamp in each time series document.
+- ``metaField``: Specifies the field that stores metadata in each time series document.
+- ``granularity``: Specifies the approximate time between consecutive timestamps. The possible
+ values are ``'seconds'``, ``'minutes'``, and ``'hours'``.
+
+.. _php-time-series-create-example:
+
+Example
+~~~~~~~
+
+This example creates the ``sept2023`` time series collection in the
+``precipitation`` database with the following configuration:
+
+- ``timeField`` is set to ``'timestamp'``
+- ``metaField`` is set to ``'location'``
+- ``granularity`` is set to ``'minutes'``
+
+.. literalinclude:: /includes/databases-collections/time-series.php
+ :start-after: start-create-ts
+ :end-before: end-create-ts
+ :language: php
+ :dedent:
+
+To verify that you successfully created the time series collection, call
+the ``MongoDB\Database::listCollections()`` method on the database and
+print the results:
+
+.. io-code-block::
+ :copyable:
+
+ .. input:: /includes/databases-collections/time-series.php
+ :start-after: start-list-colls
+ :end-before: end-list-colls
+ :language: php
+ :dedent:
+
+ .. output::
+ :language: console
+ :visible: false
+
+ MongoDB\Model\CollectionInfo Object
+ (
+ [name] => sept2023
+ [type] => timeseries
+ [options] => Array
+ (
+ …
+ )
+
+ [info] => Array
+ (
+ …
+ )
+ )
+ MongoDB\Model\CollectionInfo Object
+ (
+ [name] => system.buckets.sept2023
+ [type] => collection
+ [options] => Array
+ (
+ …
+ )
+
+ [info] => Array
+ (
+ …
+ )
+ )
+
+.. note::
+
+ MongoDB stores system data associated with time series collections
+ in the ``.system.buckets`` namespace. For more information,
+ see :manual:`database.system.buckets `
+ in the {+mdb-server+} manual.
+
+.. _php-time-series-insert:
+
+Insert Time Series Data
+-----------------------
+
+You can insert data into a time series collection by using the ``MongoDB\Collection::insertOne()``
+or ``MongoDB\Collection::insertMany()`` methods and specifying the measurement,
+timestamp, and metadata in each inserted document.
+
+.. tip::
+
+ To learn more about inserting documents into a collection, see the :ref:`php-write-insert`
+ guide.
+
+Example
+~~~~~~~
+
+This example inserts New York City precipitation data into the ``sept2023``
+time series collection created in the :ref:`Create a Time Series Collection example
+`. Each document contains the following fields:
+
+- ``precipitation_mm``, which stores precipitation measurements in millimeters
+- ``location``, which stores location metadata
+- ``timestamp``, which stores the time of the measurement collection
+
+.. literalinclude:: /includes/databases-collections/time-series.php
+ :start-after: start-insert-ts
+ :end-before: end-insert-ts
+ :language: php
+ :dedent:
+
+.. _php-time-series-query:
+
+Query Time Series Collections
+-----------------------------
+
+You can use the same syntax and conventions to query data stored in a time
+series collection as you use when performing read or aggregation operations on
+other collections. To find more information about these operations, see
+the :ref:`Additional Information ` section.
+
+.. _php-time-series-addtl-info:
+
+Additional Information
+----------------------
+
+To learn more about the concepts mentioned in this guide, see the
+following Server manual entries:
+
+- :manual:`Time Series `
+- :manual:`Create and Query a Time Series Collection `
+- :manual:`Set Granularity for Time Series Data `
+
+To learn more about performing read operations, see :ref:`php-read`.
+
+To learn more about performing aggregation operations, see the :ref:`php-aggregation`
+guide.
+
+API Documentation
+~~~~~~~~~~~~~~~~~
+
+To learn more about the methods mentioned in this guide, see the following
+API documentation:
+
+- :phpmethod:`MongoDB\Database::createCollection()`
+- :phpmethod:`MongoDB\Database::listCollections()`
+- :phpmethod:`MongoDB\Collection::insertOne()`
+- :phpmethod:`MongoDB\Collection::insertMany()`
diff --git a/source/faq.txt b/source/faq.txt
index 101f757f..5e333636 100644
--- a/source/faq.txt
+++ b/source/faq.txt
@@ -1,3 +1,5 @@
+.. _php-faq:
+
==========================
Frequently Asked Questions
==========================
diff --git a/source/get-started.txt b/source/get-started.txt
new file mode 100644
index 00000000..d9a61995
--- /dev/null
+++ b/source/get-started.txt
@@ -0,0 +1,46 @@
+.. _php-get-started:
+
+================================
+Get Started with the PHP Library
+================================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: tutorial
+
+.. meta::
+ :description: Learn how to create an app to connect to MongoDB deployment by using the PHP library.
+ :keywords: quick start, tutorial, basics
+
+.. toctree::
+
+ /get-started/download-and-install/
+ /get-started/create-a-deployment/
+ /get-started/create-a-connection-string/
+ /get-started/connect-to-mongodb/
+ /get-started/next-steps/
+
+Overview
+--------
+
+The {+php-library+} is a high-level abstraction for the MongoDB PHP extension, which
+you can use to connect to MongoDB and interact with data stored in your deployment.
+This guide shows you how to create an application that uses the {+php-library+} to
+connect to a MongoDB cluster hosted on MongoDB Atlas and query data in your cluster.
+
+.. tip::
+
+ MongoDB Atlas is a fully managed cloud database service that hosts your MongoDB
+ deployments. You can create your own free (no credit card required) MongoDB Atlas
+ deployment by following the steps in this guide.
+
+Follow this guide to connect a sample PHP application to a MongoDB Atlas
+deployment. If you prefer to connect to MongoDB using a different driver or
+programming language, see our :driver:`list of official drivers <>`.
+
diff --git a/source/get-started/connect-to-mongodb.txt b/source/get-started/connect-to-mongodb.txt
new file mode 100644
index 00000000..a205c8c5
--- /dev/null
+++ b/source/get-started/connect-to-mongodb.txt
@@ -0,0 +1,86 @@
+.. _php-connect-to-mongodb:
+
+==================
+Connect to MongoDB
+==================
+
+.. facet::
+ :name: genre
+ :values: tutorial
+
+.. meta::
+ :keywords: test connection, runnable, code example
+
+After retrieving the connection string for your MongoDB Atlas deployment,
+you can connect to the deployment from your PHP application and query
+the Atlas sample datasets.
+
+.. procedure::
+ :style: connected
+
+ .. step:: Edit your PHP application file
+
+ Copy and paste the following code into the ``quickstart.php`` file, which queries
+ the ``movies`` collection in the ``sample_mflix`` database:
+
+ .. literalinclude:: /includes/get-started/quickstart.php
+ :language: php
+ :dedent:
+
+ .. step:: Assign the connection string
+
+ Assign the ``MONGODB_URI`` environment variable to the connection string that you copied
+ from the :ref:`php-connection-string` step of this guide. You can assign this
+ variable by running a shell command or creating a ``.env`` file in your application,
+ as show in the following tabs:
+
+ .. tabs::
+
+ .. tab:: Shell Command
+ :tabid: shell
+
+ .. code-block:: sh
+
+ export MONGODB_URI=
+
+ .. tab:: .env File
+ :tabid: dotenv
+
+ .. code-block:: none
+
+ MONGODB_URI=
+
+ .. step:: Run your PHP application
+
+ In your project directory, run the following shell command to start the application:
+
+ .. code-block:: bash
+
+ php quickstart.php
+
+ The command line output contains details about the retrieved movie
+ document:
+
+ .. code-block:: none
+ :copyable: false
+
+ {
+ "_id": {
+ "$oid": "..."
+ },
+ ...
+ "rated": "R",
+ "metacritic": 80,
+ "title": "The Shawshank Redemption",
+ ...
+ }
+
+ If you encounter an error or see no output, ensure that you assigned the
+ proper connection string to the ``MONGODB_URI`` environment variable and
+ that you loaded the sample data.
+
+After you complete these steps, you have a PHP application that
+connects to your MongoDB deployment, runs a query on the sample
+data, and returns a matching document.
+
+.. include:: /includes/get-started/troubleshoot.rst
diff --git a/source/get-started/create-a-connection-string.txt b/source/get-started/create-a-connection-string.txt
new file mode 100644
index 00000000..52a096c4
--- /dev/null
+++ b/source/get-started/create-a-connection-string.txt
@@ -0,0 +1,68 @@
+.. _php-connection-string:
+
+==========================
+Create a Connection String
+==========================
+
+.. facet::
+ :name: genre
+ :values: tutorial
+
+.. meta::
+ :keywords: uri, atlas
+
+You can connect to your MongoDB deployment by providing a
+**connection URI**, also called a *connection string*, which
+instructs the driver on how to connect to a MongoDB deployment
+and how to behave while connected.
+
+The connection string includes the hostname or IP address and
+port of your deployment, the authentication mechanism, user credentials
+when applicable, and connection options.
+
+.. TODO:
+ To connect to an instance or deployment not hosted on Atlas, see
+ :ref:`php-connection-targets`.
+
+.. procedure::
+ :style: connected
+
+ .. step:: Find your MongoDB Atlas Connection String
+
+ To retrieve your connection string for the deployment that
+ you created in the :ref:`previous step `,
+ log in to your Atlas account and navigate to the
+ :guilabel:`Database` section and click the :guilabel:`Connect` button
+ for your new deployment.
+
+ .. figure:: /includes/figures/atlas_connection_select_cluster.png
+ :alt: The connect button in the clusters section of the Atlas UI
+
+ Then, select your user from the :guilabel:`Select database user`
+ selection menu. Select "PHP" from the :guilabel:`Driver` selection
+ menu and the version that best matches the version you installed
+ from the :guilabel:`Version` selection menu.
+
+ Select the :guilabel:`String` tab in the :guilabel:`Add connection string into your application code`
+ step to view only the connection string.
+
+ .. step:: Copy your Connection String
+
+ Click the button on the right of the connection string to copy it
+ to your clipboard, as shown in the following screenshot:
+
+ .. figure:: /includes/figures/atlas_connection_copy_string_php.png
+ :alt: The copy button next to the connection string in the Atlas UI
+
+ .. step:: Update the Placeholders
+
+ Paste this connection string into a file in your preferred text editor
+ and replace the ```` and ```` placeholders with
+ your database user's username and password.
+
+ Save this file to a safe location for use in the next step.
+
+After completing these steps, you have a connection string that
+corresponds to your Atlas cluster.
+
+.. include:: /includes/get-started/troubleshoot.rst
\ No newline at end of file
diff --git a/source/get-started/create-a-deployment.txt b/source/get-started/create-a-deployment.txt
new file mode 100644
index 00000000..fa72db96
--- /dev/null
+++ b/source/get-started/create-a-deployment.txt
@@ -0,0 +1,36 @@
+.. _php-create-deployment:
+
+===========================
+Create a MongoDB Deployment
+===========================
+
+.. facet::
+ :name: genre
+ :values: tutorial
+
+.. meta::
+ :keywords: cloud, host, atlas
+
+You can create a free tier MongoDB deployment on MongoDB Atlas
+to store and manage your data. MongoDB Atlas hosts and manages
+your MongoDB database in the cloud.
+
+.. procedure::
+ :style: connected
+
+ .. step:: Create a free MongoDB deployment on Atlas
+
+ Complete the :atlas:`Get Started with Atlas `
+ guide to set up a new Atlas account and load sample data into a new free
+ tier MongoDB deployment.
+
+ .. step:: Save your credentials
+
+ After you create your database user, save that user's
+ username and password to a safe location for use in an upcoming step.
+
+After you complete these steps, you have a new free tier MongoDB
+deployment on Atlas, database user credentials, and sample data loaded
+into your database.
+
+.. include:: /includes/get-started/troubleshoot.rst
\ No newline at end of file
diff --git a/source/get-started/download-and-install.txt b/source/get-started/download-and-install.txt
new file mode 100644
index 00000000..d9f15d67
--- /dev/null
+++ b/source/get-started/download-and-install.txt
@@ -0,0 +1,102 @@
+.. _php-download-and-install:
+
+====================
+Download and Install
+====================
+
+.. facet::
+ :name: genre
+ :values: tutorial
+
+.. meta::
+ :keywords: setup, composer, installation, code example
+
+.. procedure::
+ :style: connected
+
+ .. step:: Install dependencies
+
+ Before you begin developing, ensure that you have the following
+ dependencies installed on your local machine:
+
+ - :php:`PHP ` version 7.4 or later
+ - `Composer `__ version 2.0 or later
+
+ .. step:: Install the MongoDB PHP extension
+
+ Run the following command to install the ``mongodb`` PHP extension:
+
+ .. code-block:: bash
+
+ sudo pecl install mongodb
+
+ .. step:: Update your PHP configuration file
+
+ To enable the ``mongodb`` extension in your PHP configuration file, add the
+ following line to the top of your ``php.ini`` file:
+
+ .. code-block:: none
+
+ extension=mongodb.so
+
+ .. tip::
+
+ You can locate your ``php.ini`` file by running the following command
+ in your shell:
+
+ .. code-block:: bash
+
+ php --ini
+
+ .. step:: Create a project directory
+
+ From your root directory, run the following command in your shell to create
+ a directory called ``php-quickstart`` for this project:
+
+ .. code-block:: bash
+
+ mkdir php-quickstart
+
+ Select the tab corresponding to your operating system and run the following commands
+ to create a ``quickstart.php`` application file in the ``php-quickstart`` directory:
+
+ .. tabs::
+
+ .. tab:: macOS / Linux
+ :tabid: create-file-mac-linux
+
+ .. code-block:: bash
+
+ cd php-quickstart
+ touch quickstart.php
+
+ .. tab:: Windows
+ :tabid: create-file-windows
+
+ .. code-block:: bash
+
+ cd php-quickstart
+ type nul > quickstart.php
+
+ .. step:: Install the {+php-library+}
+
+ To install the {+php-library+}, run the following command in your ``php-quickstart``
+ directory:
+
+ .. code-block:: bash
+
+ composer require mongodb/mongodb
+
+ After installing the library, include Composer's ``autoload.php`` file by adding the
+ following code to the top of your ``quickstart.php`` file:
+
+ .. code-block:: php
+
+ ` section.
+- Learn how to perform write operations in the :ref:`` section.
\ No newline at end of file
diff --git a/source/includes/aggregation.php b/source/includes/aggregation.php
new file mode 100644
index 00000000..e8b1a7f9
--- /dev/null
+++ b/source/includes/aggregation.php
@@ -0,0 +1,40 @@
+sample_restaurants->restaurants;
+
+// Retrieves documents with a cuisine value of "Bakery", groups them by "borough", and
+// counts each borough's matching documents
+// start-match-group
+$pipeline = [
+ ['$match' => ['cuisine' => 'Bakery']],
+ ['$group' => ['_id' => '$borough', 'count' => ['$sum' => 1]]],
+];
+
+$cursor = $collection->aggregate($pipeline);
+
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-match-group
+
+// Performs the same aggregation operation as above but asks MongoDB to explain it
+// start-explain
+$pipeline = [
+ ['$match' => ['cuisine' => 'Bakery']],
+ ['$group' => ['_id' => '$borough', 'count' => ['$sum' => 1]]],
+];
+
+$aggregate = new MongoDB\Operation\Aggregate(
+ $collection->getDatabaseName(),
+ $collection->getCollectionName(),
+ $pipeline
+);
+
+$result = $collection->explain($aggregate);
+echo json_encode($result), PHP_EOL;
+// end-explain
+
diff --git a/source/includes/authentication.php b/source/includes/authentication.php
new file mode 100644
index 00000000..7810406b
--- /dev/null
+++ b/source/includes/authentication.php
@@ -0,0 +1,89 @@
+ '',
+ 'password' => '',
+ 'authSource' => '',
+ 'authMechanism' => 'SCRAM-SHA-256',
+];
+
+$client = new MongoDB\Client(
+ 'mongodb://:',
+ $uriOptions,
+);
+// end-scram-sha-256-client
+
+// start-scram-sha-256-uri
+$uri = 'mongodb://:@:/?authSource=admin&authMechanism=SCRAM-SHA-256';
+$client = new MongoDB\Client($uri);
+// end-scram-sha-256-uri
+
+// start-scram-sha-1-client
+$uriOptions = [
+ 'username' => '',
+ 'password' => '',
+ 'authSource' => '',
+ 'authMechanism' => 'SCRAM-SHA-1',
+];
+
+$client = new MongoDB\Client(
+ 'mongodb://:',
+ $uriOptions,
+);
+// end-scram-sha-1-client
+
+// start-scram-sha-1-uri
+$uri = 'mongodb://:@:/?authSource=admin&authMechanism=SCRAM-SHA-1';
+$client = new MongoDB\Client($uri);
+// end-scram-sha-1-uri
+
+// start-mongodb-X509-client
+$uriOptions = [
+ 'tls' => true,
+ 'tlsCertificateKeyFile' => '',
+ 'authMechanism' => 'MONGODB-X509',
+];
+
+$client = new MongoDB\Client(
+ 'mongodb://:',
+ $uriOptions,
+);
+// end-mongodb-X509-client
+
+// start-mongodb-X509-uri
+$uri = 'mongodb://:/?tls=true&tlsCertificateKeyFile=&authMechanism=MONGODB-X509';
+$client = new MongoDB\Client($uri);
+// end-mongodb-X509-uri
+
+// start-mongodb-aws-client
+$uriOptions = [
+ 'username' => '',
+ 'password' => '',
+ 'authMechanism' => 'MONGODB-AWS',
+];
+
+$client = new MongoDB\Client(
+ 'mongodb://:',
+ $uriOptions,
+);
+// end-mongodb-aws-client
+
+// start-mongodb-aws-uri
+$uri = 'mongodb://:@:/?authMechanism=MONGODB-AWS';
+$client = new MongoDB\Client($uri);
+// end-mongodb-aws-uri
+
+// start-mongodb-aws-env-client
+$client = new MongoDB\Client(
+ 'mongodb://:',
+ ['authMechanism' => 'MONGODB-AWS']
+);
+// end-mongodb-aws-env-client
+
+// start-mongodb-aws-env-uri
+$uri = 'mongodb://:/?authMechanism=MONGODB-AWS';
+$client = new MongoDB\Client($uri);
+// end-mongodb-aws-env-uri
diff --git a/source/includes/connect/atlas.php b/source/includes/connect/atlas.php
new file mode 100644
index 00000000..43bb4ab2
--- /dev/null
+++ b/source/includes/connect/atlas.php
@@ -0,0 +1,18 @@
+';
+
+// Create a MongoDB client with server API options
+$client = new MongoDB\Client($uri, [], [
+ 'serverApi' => new MongoDB\Driver\ServerApi('1')
+]);
+
+// Ping the server to verify that the connection works
+$admin = $client->admin;
+$command = new MongoDB\Driver\Command(['ping' => 1]);
+$result = $admin->command($command)->toArray();
+
+echo json_encode($result), PHP_EOL;
+echo 'Pinged your deployment. You successfully connected to MongoDB!\n';
+
diff --git a/source/includes/connect/ca-dir.php b/source/includes/connect/ca-dir.php
new file mode 100644
index 00000000..03e88108
--- /dev/null
+++ b/source/includes/connect/ca-dir.php
@@ -0,0 +1,11 @@
+$uri = 'mongodb://:';
+
+$uriOptions = [
+ 'tls' => true,
+];
+
+$driverOptions = [
+ 'ca_dir' => '/path/to/search/'
+];
+
+$client = new MongoDB\Client($uri, $uriOptions, $driverOptions);
diff --git a/source/includes/connect/ca-file-tabs.rst b/source/includes/connect/ca-file-tabs.rst
new file mode 100644
index 00000000..57bfd343
--- /dev/null
+++ b/source/includes/connect/ca-file-tabs.rst
@@ -0,0 +1,23 @@
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: mongoclient
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:';
+
+ $options = [
+ 'tls' => true,
+ 'tlsCAFile' => '/path/to/ca.pem'
+ ];
+
+ $client = new MongoDB\Client($uri, $options);
+
+ .. tab:: Connection String
+ :tabid: connectionstring
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:/?tls=true&tlsCAFile=/path/to/ca.pem';
+ $client = MongoDB\Client($uri);
\ No newline at end of file
diff --git a/source/includes/connect/client-cert-tabs.rst b/source/includes/connect/client-cert-tabs.rst
new file mode 100644
index 00000000..a93a9185
--- /dev/null
+++ b/source/includes/connect/client-cert-tabs.rst
@@ -0,0 +1,23 @@
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: mongoclient
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:';
+
+ $options = [
+ 'tls' => true,
+ 'tlsCertificateKeyFile' => '/path/to/client.pem'
+ ];
+
+ $client = new MongoDB\Client($uri, $options);
+
+ .. tab:: Connection String
+ :tabid: connectionstring
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:/?tls=true&tlsCertificateKeyFile=/path/to/client.pem';
+ $client = MongoDB\Client($uri);
\ No newline at end of file
diff --git a/source/includes/connect/client.php b/source/includes/connect/client.php
new file mode 100644
index 00000000..48d40f4e
--- /dev/null
+++ b/source/includes/connect/client.php
@@ -0,0 +1,3 @@
+:/?tls=true&tlsCertificateKeyFile=/path/to/file.pem";
+
+// Create a MongoDB client
+$client = new MongoDB\Client($uri);
+// end-connection-uri
+
+// start-client-options
+// Replace the placeholders with your actual hostname and port
+$uri = "mongodb://:/";
+
+// Set the connection options
+// Replace the placeholder with the actual path to the certificate key file
+$uriOptions = [
+ 'tls' => true,
+ 'tlsCertificateKeyFile' => '/path/to/file.pem'
+];
+
+// Create a MongoDB client with the URI and options
+$client = new Client($uri, $uriOptions);
+// end-client-options
diff --git a/source/includes/connect/crl-file.php b/source/includes/connect/crl-file.php
new file mode 100644
index 00000000..8904c0e4
--- /dev/null
+++ b/source/includes/connect/crl-file.php
@@ -0,0 +1,11 @@
+$uri = 'mongodb://:';
+
+$uriOptions = [
+ 'tls' => true,
+];
+
+$driverOptions = [
+ 'crl_file' => '/path/to/file.pem'
+];
+
+$client = new MongoDB\Client($uri, $uriOptions, $driverOptions);
diff --git a/source/includes/connect/crl-tabs.rst b/source/includes/connect/crl-tabs.rst
new file mode 100644
index 00000000..3784ce06
--- /dev/null
+++ b/source/includes/connect/crl-tabs.rst
@@ -0,0 +1,23 @@
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: mongoclient
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:';
+
+ $options = [
+ 'tls' => true,
+ 'tlsCRLFile' => '/path/to/crl.pem'
+ ];
+
+ $client = new MongoDB\Client($uri, $options);
+
+ .. tab:: Connection String
+ :tabid: connectionstring
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:/?tls=true&tlsCRLFile=/path/to/crl.pem';
+ $client = MongoDB\Client($uri);
\ No newline at end of file
diff --git a/source/includes/connect/direct-connection.php b/source/includes/connect/direct-connection.php
new file mode 100644
index 00000000..665bc3ae
--- /dev/null
+++ b/source/includes/connect/direct-connection.php
@@ -0,0 +1,7 @@
+:/?directConnection=true';
+
+// Create a MongoDB client
+$client = new MongoDB\Client($uri);
\ No newline at end of file
diff --git a/source/includes/connect/disable-cert-validation-tabs.rst b/source/includes/connect/disable-cert-validation-tabs.rst
new file mode 100644
index 00000000..60e77093
--- /dev/null
+++ b/source/includes/connect/disable-cert-validation-tabs.rst
@@ -0,0 +1,23 @@
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: mongoclient
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:';
+
+ $options = [
+ 'tls' => true,
+ 'tlsAllowInvalidCertificates' => true
+ ];
+
+ $client = new MongoDB\Client($uri, $options);
+
+ .. tab:: Connection String
+ :tabid: connectionstring
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:/?tls=true&tlsAllowInvalidCertificates=true';
+ $client = MongoDB\Client($uri);
\ No newline at end of file
diff --git a/source/includes/connect/disable-host-verification-tabs.rst b/source/includes/connect/disable-host-verification-tabs.rst
new file mode 100644
index 00000000..96cc4cfc
--- /dev/null
+++ b/source/includes/connect/disable-host-verification-tabs.rst
@@ -0,0 +1,23 @@
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: mongoclient
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:';
+
+ $options = [
+ 'tls' => true,
+ 'tlsAllowInvalidHostnames' => true
+ ];
+
+ $client = new MongoDB\Client($uri, $options);
+
+ .. tab:: Connection String
+ :tabid: connectionstring
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:/?tls=true&tlsAllowInvalidHostnames=true';
+ $client = MongoDB\Client($uri);
\ No newline at end of file
diff --git a/source/includes/connect/insecure-tls-tabs.rst b/source/includes/connect/insecure-tls-tabs.rst
new file mode 100644
index 00000000..e04e56ea
--- /dev/null
+++ b/source/includes/connect/insecure-tls-tabs.rst
@@ -0,0 +1,23 @@
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: mongoclient
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:';
+
+ $options = [
+ 'tls' => true,
+ 'tlsInsecure' => true
+ ];
+
+ $client = new MongoDB\Client($uri, $options);
+
+ .. tab:: Connection String
+ :tabid: connectionstring
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:/?tls=true&tlsInsecure=true';
+ $client = MongoDB\Client($uri);
\ No newline at end of file
diff --git a/source/includes/connect/key-file-password.rst b/source/includes/connect/key-file-password.rst
new file mode 100644
index 00000000..a6b2f8ea
--- /dev/null
+++ b/source/includes/connect/key-file-password.rst
@@ -0,0 +1,24 @@
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: mongoclient
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:';
+
+ $options = [
+ 'tls' => true,
+ 'tlsCertificateKeyFile' => '/path/to/client.pem',
+ 'tlsCertificateKeyFilePassword' => ''
+ ];
+
+ $client = new MongoDB\Client($uri, $options);
+
+ .. tab:: Connection String
+ :tabid: connectionstring
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:/?tls=true&tlsCertificateKeyFile=/path/to/client.pem&tlsCertificateKeyFilePassword=';
+ $client = MongoDB\Client($uri);
\ No newline at end of file
diff --git a/source/includes/connect/ocsp-tabs.rst b/source/includes/connect/ocsp-tabs.rst
new file mode 100644
index 00000000..467fed14
--- /dev/null
+++ b/source/includes/connect/ocsp-tabs.rst
@@ -0,0 +1,23 @@
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: mongoclient
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:';
+
+ $options = [
+ 'tls' => true,
+ 'tlsDisableOCSPEndpointCheck' => true
+ ];
+
+ $client = new MongoDB\Client($uri, $options);
+
+ .. tab:: Connection String
+ :tabid: connectionstring
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:/?tls=true&tlsDisableOCSPEndpointCheck=true';
+ $client = MongoDB\Client($uri);
\ No newline at end of file
diff --git a/source/includes/connect/replica-set.php b/source/includes/connect/replica-set.php
new file mode 100644
index 00000000..cd8840fb
--- /dev/null
+++ b/source/includes/connect/replica-set.php
@@ -0,0 +1,6 @@
+:";
+
+$driverOptions = ['serverApi' => new MongoDB\Driver\ServerApi('1')];
+
+$client = new MongoDB\Client($uri, [], $driverOptions);
+// end-specify-v1
+
+// start-stable-api-options
+$uri = "mongodb://:";
+
+$serverApi = new MongoDB\Driver\ServerApi('1', strict: true, deprecationErrors: true);
+$driverOptions = ['serverApi' => $serverApi];
+
+$client = new MongoDB\Client($uri, [], $driverOptions);
+// end-stable-api-options
diff --git a/source/includes/connect/tls-tabs.rst b/source/includes/connect/tls-tabs.rst
new file mode 100644
index 00000000..b28918a3
--- /dev/null
+++ b/source/includes/connect/tls-tabs.rst
@@ -0,0 +1,22 @@
+.. tabs::
+
+ .. tab:: MongoDB\\Client
+ :tabid: mongoclient
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:';
+
+ $options = [
+ 'tls' => true
+ ];
+
+ $client = new MongoDB\Client($uri, $options);
+
+ .. tab:: Connection String
+ :tabid: connectionstring
+
+ .. code-block:: php
+
+ $uri = 'mongodb://:/?tls=true';
+ $client = MongoDB\Client($uri);
\ No newline at end of file
diff --git a/source/includes/databases-collections/databases-collections.php b/source/includes/databases-collections/databases-collections.php
new file mode 100644
index 00000000..eb4dde74
--- /dev/null
+++ b/source/includes/databases-collections/databases-collections.php
@@ -0,0 +1,105 @@
+selectDatabase('test_database');
+// end-access-database
+
+// Invokes the __get() method to access the "test_database" database
+// start-access-database-short
+$db = $client->test_database;
+// end-access-database-short
+
+// Accesses the "test_collection" collection
+// start-access-collection
+$collection = $client->test_database->selectCollection('test_collection');
+// end-access-collection
+
+// Invokes the __get() method to access the "test_collection" collection
+// start-access-collection-short
+$collection = $db->test_collection;
+// end-access-collection-short
+
+// Explicitly creates the "example_collection" collection
+// start-create-collection
+$result = $client->test_database->createCollection('example_collection');
+// end-create-collection
+
+// Lists the collections in the "test_database" database
+// start-find-collections
+foreach ($client->test_database->listCollections() as $collectionInfo) {
+ print_r($collectionInfo) . PHP_EOL;
+}
+// end-find-collections
+
+// Deletes the "test_collection" collection
+// start-drop-collection
+$client->test_database->dropCollection('test_collection');
+// end-drop-collection
+
+// Sets read and write settings for the "test_database" database
+// start-database-settings
+$readPreference = new ReadPreference(ReadPreference::RP_SECONDARY);
+$readConcern = new ReadConcern(ReadConcern::LOCAL);
+$writeConcern = new WriteConcern(WriteConcern::MAJORITY);
+
+$db = $client->selectDatabase('test_database', [
+ 'readPreference' => $readPreference,
+ 'readConcern' => $readConcern,
+ 'writeConcern' => $writeConcern,
+]);
+// end-database-settings
+
+// Sets read and write settings for the "test_collection" collection
+// start-collection-settings
+$readPreference = new ReadPreference(ReadPreference::RP_PRIMARY);
+$readConcern = new ReadConcern(ReadConcern::AVAILABLE);
+$writeConcern = new WriteConcern(WriteConcern::MAJORITY);
+
+$collection = $client->selectCollection('test_database', 'test_collection', [
+ 'readPreference' => $readPreference,
+ 'readConcern' => $readConcern,
+ 'writeConcern' => $writeConcern,
+]);
+
+// end-collection-settings
+
+// Instructs the library to prefer reads from secondary replica set members
+// located in New York, followed by a secondary in San Francisco, and
+// lastly fall back to any secondary.
+// start-tag-set
+$readPreference = new ReadPreference(
+ ReadPreference::RP_SECONDARY,
+ [
+ ['dc' => 'ny'],
+ ['dc' => 'sf'],
+ [],
+ ],
+);
+
+$db = $client->selectDatabase(
+ 'test_database',
+ ['readPreference' => $readPreference],
+);
+
+// end-tag-set
+
+// Instructs the library to distribute reads between members within 35 milliseconds
+// of the closest member's ping time
+// start-local-threshold
+$options = [
+ 'replicaSet' => 'repl0',
+ 'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
+ 'localThresholdMS' => 35,
+];
+
+$client = new Client('', [], $options);
+// end-local-threshold
diff --git a/source/includes/databases-collections/time-series.php b/source/includes/databases-collections/time-series.php
new file mode 100644
index 00000000..35b005e2
--- /dev/null
+++ b/source/includes/databases-collections/time-series.php
@@ -0,0 +1,48 @@
+precipitation;
+
+$options = [
+ 'timeseries' => [
+ 'timeField' => 'timestamp',
+ 'metaField' => 'location',
+ 'granularity' => 'minutes',
+ ]
+];
+
+$collection = $db->createCollection('sept2023', $options);
+// end-create-ts
+
+// Lists the collections in the "precipitation" database
+// start-list-colls
+$cursor = $db->listCollections();
+
+foreach ($cursor as $collectionInfo) {
+ print_r($collectionInfo) . PHP_EOL;
+}
+// end-list-colls
+
+// Inserts precipitation time series data about New York City into the collection
+// start-insert-ts
+$collection = $db->sept2023;
+$result = $collection->insertMany(
+ [
+ [
+ 'precipitation_mm' => 0.5,
+ 'location' => 'New York City',
+ 'timestamp' => new MongoDB\BSON\UTCDateTime(1694829060000),
+ ],
+ [
+ 'precipitation_mm' => 2.8,
+ 'location' => 'New York City',
+ 'timestamp' => new MongoDB\BSON\UTCDateTime(1695594780000),
+ ],
+ ]
+);
+// end-insert-ts
diff --git a/source/includes/extracts-bucket-option.yaml b/source/includes/extracts-bucket-option.yaml
index a3eb915f..1ca8a553 100644
--- a/source/includes/extracts-bucket-option.yaml
+++ b/source/includes/extracts-bucket-option.yaml
@@ -1,6 +1,6 @@
ref: bucket-option-codec
content: |
- The :doc:`codec ` to use for encoding or decoding documents.
+ The :doc:`codec ` to use for encoding or decoding documents.
This option is mutually exclusive with the ``typeMap`` option.
Defaults to the bucket's codec. Inheritance for a default ``codec`` option
diff --git a/source/includes/extracts-collection-option.yaml b/source/includes/extracts-collection-option.yaml
index ecc82a42..c293dc62 100644
--- a/source/includes/extracts-collection-option.yaml
+++ b/source/includes/extracts-collection-option.yaml
@@ -1,6 +1,6 @@
ref: collection-option-codec
content: |
- The :doc:`codec ` to use for encoding or decoding documents.
+ The :doc:`codec ` to use for encoding or decoding documents.
This option is mutually exclusive with the ``typeMap`` option.
Defaults to the collection's codec. Inheritance for a default ``codec`` option
diff --git a/source/includes/extracts-common-option.yaml b/source/includes/extracts-common-option.yaml
index 39cab355..68702d6e 100644
--- a/source/includes/extracts-common-option.yaml
+++ b/source/includes/extracts-common-option.yaml
@@ -1,6 +1,6 @@
ref: common-option-codec
content: |
- The :doc:`codec ` to use for encoding or decoding documents.
+ The :doc:`codec ` to use for encoding or decoding documents.
This option is mutually exclusive with the ``typeMap`` option.
---
ref: common-option-collation
diff --git a/source/includes/figures/GridFS-upload.png b/source/includes/figures/GridFS-upload.png
new file mode 100644
index 00000000..2207752b
Binary files /dev/null and b/source/includes/figures/GridFS-upload.png differ
diff --git a/source/includes/figures/atlas_connection_copy_string_php.png b/source/includes/figures/atlas_connection_copy_string_php.png
new file mode 100644
index 00000000..b15ef37a
Binary files /dev/null and b/source/includes/figures/atlas_connection_copy_string_php.png differ
diff --git a/source/includes/figures/atlas_connection_select_cluster.png b/source/includes/figures/atlas_connection_select_cluster.png
new file mode 100644
index 00000000..52d827d6
Binary files /dev/null and b/source/includes/figures/atlas_connection_select_cluster.png differ
diff --git a/source/includes/get-started/quickstart.php b/source/includes/get-started/quickstart.php
new file mode 100644
index 00000000..58237258
--- /dev/null
+++ b/source/includes/get-started/quickstart.php
@@ -0,0 +1,20 @@
+sample_mflix->movies;
+
+$filter = ['title' => 'The Shawshank Redemption'];
+$result = $collection->findOne($filter);
+
+if ($result) {
+ echo json_encode($result, JSON_PRETTY_PRINT);
+} else {
+ echo 'Document not found';
+}
diff --git a/source/includes/get-started/troubleshoot.rst b/source/includes/get-started/troubleshoot.rst
new file mode 100644
index 00000000..08d6e428
--- /dev/null
+++ b/source/includes/get-started/troubleshoot.rst
@@ -0,0 +1,6 @@
+.. note::
+
+ If you run into issues on this step, ask for help in the
+ :community-forum:`MongoDB Community Forums `
+ or submit feedback by using the :guilabel:`Rate this page`
+ tab on the right or bottom right side of this page.
\ No newline at end of file
diff --git a/source/includes/indexes/indexes.php b/source/includes/indexes/indexes.php
new file mode 100644
index 00000000..3b293fb1
--- /dev/null
+++ b/source/includes/indexes/indexes.php
@@ -0,0 +1,114 @@
+sample_mflix;
+$collection = $database->movies;
+
+// start-list-indexes
+foreach ($collection->listIndexes() as $indexInfo) {
+ echo $indexInfo;
+}
+// end-list-indexes
+
+// start-remove-index
+$collection->dropIndex('_title_');
+// end-remove-index
+
+// start-remove-all-indexes
+$collection->dropIndexes();
+// end-remove-all-indexes
+
+// start-index-single
+$indexName = $collection->createIndex(['title' => 1]);
+// end-index-single
+
+// start-index-single-query
+$document = $collection->findOne(['title' => 'Sweethearts']);
+echo json_encode($document), PHP_EOL;
+// end-index-single-query
+
+// start-index-compound
+$indexName = $collection->createIndex(
+ ['title' => 1, 'year' => 1]
+);
+// end-index-compound
+
+// start-compound-query
+$document = $collection->findOne(
+ ['title' => ['$regex' => 'Sunrise'],
+ 'year' => ['$gte' => 1990]]
+);
+echo json_encode($document), PHP_EOL;
+// end-compound-query
+
+// start-multikey
+$indexName = $collection->createIndex(['cast' => 1]);
+// end-multikey
+
+// start-index-array-query
+$document = $collection->findOne(
+ ['cast' => ['$in' => ['Aamir Khan', 'Kajol']]]
+);
+echo json_encode($document), PHP_EOL;
+// end-index-array-query
+
+// start-create-search-index
+$indexName = $collection->createSearchIndex(
+ ['mappings' => ['dynamic' => true]],
+ ['name' => 'mySearchIdx']
+);
+// end-create-search-index
+
+// start-create-search-indexes
+$indexNames = $collection->createSearchIndexes(
+ [
+ [
+ 'name' => 'SearchIdx_dynamic',
+ 'definition' => ['mappings' => ['dynamic' => true]],
+ ],
+ [
+ 'name' => 'SearchIdx_simple',
+ 'definition' => [
+ 'mappings' => [
+ 'dynamic' => false,
+ 'fields' => [
+ 'title' => [
+ 'type' => 'string',
+ 'analyzer' => 'lucene.simple'
+ ]
+ ]
+ ]
+ ],
+ ],
+ ]
+);
+// end-create-search-indexes
+
+// start-list-search-indexes
+foreach ($collection->listSearchIndexes() as $indexInfo) {
+ echo json_encode($indexInfo), PHP_EOL;
+}
+// end-list-search-indexes
+
+// start-update-search-indexes
+$collection->updateSearchIndex(
+ 'mySearchIdx',
+ ['mappings' => [
+ 'dynamic' => false,
+ 'fields' => [
+ 'title' => [
+ 'type' => 'string',
+ 'analyzer' => 'lucene.simple'
+ ]
+ ]
+ ]]
+);
+// end-update-search-indexes
+
+// start-delete-search-index
+$collection->dropSearchIndex('mySearchIdx');
+// end-delete-search-index
\ No newline at end of file
diff --git a/source/includes/language-compatibility-table-php.rst b/source/includes/language-compatibility-table-php.rst
new file mode 100644
index 00000000..c50e52b3
--- /dev/null
+++ b/source/includes/language-compatibility-table-php.rst
@@ -0,0 +1,49 @@
+.. list-table::
+ :header-rows: 1
+ :stub-columns: 1
+ :class: compatibility-large
+
+ * - PHP Driver Versions
+ - PHP 8.4
+ - PHP 8.3
+ - PHP 8.2
+ - PHP 8.1
+ - PHP 8.0
+ - PHP 7.4
+ - PHP 7.3
+
+ * - ext + lib 1.20
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ -
+
+ * - ext + lib 1.17 to 1.19
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ -
+ -
+
+ * - ext + lib 1.16
+ -
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+
+ * - ext + lib 1.15
+ -
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
\ No newline at end of file
diff --git a/source/includes/mongodb-compatibility-table-php.rst b/source/includes/mongodb-compatibility-table-php.rst
new file mode 100644
index 00000000..febec5a4
--- /dev/null
+++ b/source/includes/mongodb-compatibility-table-php.rst
@@ -0,0 +1,48 @@
+.. list-table::
+ :header-rows: 1
+ :stub-columns: 1
+ :class: compatibility-large
+
+ * - PHP Driver Versions
+ - MongoDB 8.0
+ - MongoDB 7.0
+ - MongoDB 6.0
+ - MongoDB 5.0
+ - MongoDB 4.4
+ - MongoDB 4.2
+ - MongoDB 4.0
+ - MongoDB 3.6
+ - MongoDB 3.4
+
+ * - ext + lib 1.20
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ -
+ -
+
+ * - ext + lib 1.16 to 1.19
+ - ⊛
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ -
+
+ * - ext + lib 1.15
+ - ⊛
+ - ⊛
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ - ✓
+ -
\ No newline at end of file
diff --git a/source/includes/monitoring/sdam.php b/source/includes/monitoring/sdam.php
new file mode 100644
index 00000000..1647f9d9
--- /dev/null
+++ b/source/includes/monitoring/sdam.php
@@ -0,0 +1,49 @@
+stream = $stream;
+ }
+
+ public function serverOpening(MongoDB\Driver\Monitoring\ServerOpeningEvent $event): void {
+ fprintf(
+ $this->stream,
+ 'Server opening on %s:%s\n',
+ $event->getHost(),
+ $event->getPort(),
+ );
+ }
+
+ public function serverClosed(MongoDB\Driver\Monitoring\ServerClosedEvent $event): void {}
+ public function serverChanged(MongoDB\Driver\Monitoring\ServerChangedEvent $event): void {}
+ public function serverHeartbeatFailed(MongoDB\Driver\Monitoring\ServerHeartbeatFailedEvent $event): void {}
+ public function serverHeartbeatStarted(MongoDB\Driver\Monitoring\ServerHeartbeatStartedEvent $event): void {}
+ public function serverHeartbeatSucceeded(MongoDB\Driver\Monitoring\ServerHeartbeatSucceededEvent $event): void {}
+ public function topologyChanged(MongoDB\Driver\Monitoring\TopologyChangedEvent $event): void {}
+ public function topologyClosed(MongoDB\Driver\Monitoring\TopologyClosedEvent $event): void {}
+ public function topologyOpening(MongoDB\Driver\Monitoring\TopologyOpeningEvent $event): void {}
+}
+// end-mysubscriber
+
+$uri = getenv('MONGODB_URI') ?: throw new RuntimeException('Set the MONGODB_URI variable to your connection URI');
+$client = new MongoDB\Client($uri);
+
+$collection = $client->db->my_coll;
+
+// start-add-sub
+$subscriber = new MySubscriber(STDERR);
+$client->addSubscriber($subscriber);
+// end-add-sub
+
+$collection->insertOne(['x' => 100]);
+
+// start-remove-sub
+$client->removeSubscriber($subscriber);
+// end-remove-sub
\ No newline at end of file
diff --git a/source/includes/read-write-pref.php b/source/includes/read-write-pref.php
new file mode 100644
index 00000000..9c0c8ed9
--- /dev/null
+++ b/source/includes/read-write-pref.php
@@ -0,0 +1,93 @@
+ 'secondary',
+ 'readConcernLevel' => 'local',
+ 'w' => '2',
+];
+
+$client = new Client('mongodb://localhost:27017', $clientOptions);
+// end-client-settings
+
+// start-client-settings-uri
+$uri = 'mongodb://localhost:27017/?readPreference=secondary&readConcernLevel=local&w=2';
+$client = new Client($uri);
+// end-client-settings-uri
+
+// start-session-settings
+$sessionOptions = [
+ 'readPreference' => new ReadPreference(ReadPreference::PRIMARY_PREFERRED),
+ 'readConcern' => new ReadConcern(ReadConcern::LOCAL),
+ 'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+];
+
+$session = $client->startSession($sessionOptions);
+// end-session-settings
+
+// start-transaction-settings
+$transactionOptions = [
+ 'readPreference' => new ReadPreference(ReadPreference::PRIMARY),
+ 'readConcern' => new ReadConcern(ReadConcern::MAJORITY),
+ 'writeConcern' => new WriteConcern(1),
+];
+
+$session->startTransaction($transactionOptions);
+// end-transaction-settings
+
+// Sets read and write settings for the "test_database" database
+// start-database-settings
+$db = $client->selectDatabase('test_database', [
+ 'readPreference' => new ReadPreference(ReadPreference::PRIMARY_PREFERRED),
+ 'readConcern' => new ReadConcern(ReadConcern::AVAILABLE),
+ 'writeConcern' => new WriteConcern(WriteConcern::MAJORITY),
+]);
+// end-database-settings
+
+// Sets read and write settings for the "test_collection" collection
+// start-collection-settings
+$collection = $client->selectCollection('test_database', 'test_collection', [
+ 'readPreference' => new ReadPreference(ReadPreference::SECONDARY_PREFERRED),
+ 'readConcern' => new ReadConcern(ReadConcern::AVAILABLE),
+ 'writeConcern' => new WriteConcern(0),
+]);
+
+// end-collection-settings
+
+// Instructs the library to prefer reads from secondary replica set members
+// located in New York, followed by a secondary in San Francisco, and
+// lastly fall back to any secondary.
+// start-tag-set
+$readPreference = new ReadPreference(
+ ReadPreference::RP_SECONDARY,
+ [
+ ['dc' => 'ny'],
+ ['dc' => 'sf'],
+ [],
+ ],
+);
+
+$db = $client->selectDatabase(
+ 'test_database',
+ ['readPreference' => $readPreference],
+);
+
+// end-tag-set
+
+// Instructs the library to distribute reads between members within 35 milliseconds
+// of the closest member's ping time
+// start-local-threshold
+$options = [
+ 'replicaSet' => 'repl0',
+ 'readPreference' => new ReadPreference(ReadPreference::RP_SECONDARY_PREFERRED),
+ 'localThresholdMS' => 35,
+];
+
+$client = new Client('mongodb://localhost:27017', [], $options);
+// end-local-threshold
diff --git a/source/includes/read/change-streams.php b/source/includes/read/change-streams.php
new file mode 100644
index 00000000..b00ced02
--- /dev/null
+++ b/source/includes/read/change-streams.php
@@ -0,0 +1,78 @@
+toRelaxedExtendedJSON();
+}
+// end-to-json
+
+$uri = getenv('MONGODB_URI') ?: throw new RuntimeException('Set the MONGODB_URI variable to your Atlas URI that connects to the sample dataset');
+$client = new MongoDB\Client($uri);
+
+// start-db-coll
+$collection = $client->sample_restaurants->restaurants;
+// end-db-coll
+
+// Monitors and prints changes to the "restaurants" collection
+// start-open-change-stream
+$changeStream = $collection->watch();
+
+for ($changeStream->rewind(); true; $changeStream->next()) {
+ if ( ! $changeStream->valid()) {
+ continue;
+ }
+ $event = $changeStream->current();
+ echo toJSON($event), PHP_EOL;
+
+ if ($event['operationType'] === 'invalidate') {
+ break;
+ }
+}
+// end-open-change-stream
+
+// Updates a document that has a "name" value of "Blarney Castle"
+// start-update-for-change-stream
+$result = $collection->updateOne(
+ ['name' => 'Blarney Castle'],
+ ['$set' => ['cuisine' => 'Irish']]
+);
+// end-update-for-change-stream
+
+// Passes a pipeline argument to watch() to monitor only update operations
+// start-change-stream-pipeline
+$pipeline = [['$match' => ['operationType' => 'update']]];
+$changeStream = $collection->watch($pipeline);
+
+for ($changeStream->rewind(); true; $changeStream->next()) {
+ if ( ! $changeStream->valid()) {
+ continue;
+ }
+ $event = $changeStream->current();
+ echo toJSON($event), PHP_EOL;
+
+ if ($event['operationType'] === 'invalidate') {
+ break;
+ }
+}
+// end-change-stream-pipeline
+
+// Passes an options argument to watch() to include the post-image of updated documents
+// start-change-stream-post-image
+$options = ['fullDocument' => MongoDB\Operation\Watch::FULL_DOCUMENT_UPDATE_LOOKUP];
+$changeStream = $collection->watch([], $options);
+
+for ($changeStream->rewind(); true; $changeStream->next()) {
+ if ( ! $changeStream->valid()) {
+ continue;
+ }
+ $event = $changeStream->current();
+ echo toJSON($event), PHP_EOL;
+
+ if ($event['operationType'] === 'invalidate') {
+ break;
+ }
+}
+// end-change-stream-post-image
+
diff --git a/source/includes/read/count.php b/source/includes/read/count.php
new file mode 100644
index 00000000..e76bbedf
--- /dev/null
+++ b/source/includes/read/count.php
@@ -0,0 +1,44 @@
+sample_training->companies;
+// end-db-coll
+
+// Counts all documents in the collection
+// start-count-all
+$result = $collection->countDocuments([]);
+echo 'Number of documents: ', $result;
+// end-count-all
+
+// Counts documents that have a "founded_year" value of 2010
+// start-count-accurate
+$result = $collection->countDocuments(['founded_year' => 2010]);
+echo 'Number of companies founded in 2010: ', $result;
+// end-count-accurate
+
+// Counts a maximum of 100 documents that have a "number_of_employees" value of 50
+// start-modify-accurate
+$result = $collection->countDocuments(
+ ['number_of_employees' => 50],
+ ['limit' => 100]
+);
+echo 'Number of companies with 50 employees: ', $result;
+// end-modify-accurate
+
+// Estimates the number of documents in the collection
+// start-count-estimate
+$result = $collection->estimatedDocumentCount();
+echo 'Estimated number of documents: ', $result;
+// end-count-estimate
+
+// Estimates the number of documents in the collection and sets a time limit on the operation
+// start-modify-estimate
+$result = $collection->estimatedDocumentCount(['maxTimeMS' => 1000]);
+echo 'Estimated number of documents: ', $result;
+// end-modify-estimate
diff --git a/source/includes/read/cursor.php b/source/includes/read/cursor.php
new file mode 100644
index 00000000..7ea0648a
--- /dev/null
+++ b/source/includes/read/cursor.php
@@ -0,0 +1,64 @@
+sample_restaurants->restaurants;
+// end-db-coll
+
+// Iterates over and prints all documents that have a "name" value of "Dunkin' Donuts"
+// start-cursor-iterate
+$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-cursor-iterate
+
+// Retrieves and prints the first document stored in the cursor
+// start-cursor-first
+$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
+$cursor->rewind();
+echo json_encode($cursor->current());
+// end-cursor-first
+
+// Converts the documents stored in a cursor to an array
+// start-cursor-array
+$cursor = $collection->find(['name' => 'Dunkin\' Donuts']);
+$array_results = $cursor->toArray();
+// end-cursor-array
+
+// Creates a collection with a maximum size and inserts documents representing vegetables
+// start-capped-coll
+$db = $client->db;
+$create_coll = $db->createCollection(
+ 'vegetables',
+ ['capped' => true, 'size' => 1024 * 1024]
+);
+
+$vegetables = [
+ ['name' => 'cauliflower'],
+ ['name' => 'zucchini']
+];
+
+$collection = $db->vegetables;
+$result = $collection->insertMany($vegetables);
+// end-capped-coll
+
+// Iterates over the initial query results and continues iterating until three documents are stored in the cursor
+// by using a tailable cursor
+// start-tailable
+$cursor = $collection->find([], ['cursorType' => MongoDB\Operation\Find::TAILABLE]);
+$cursor->rewind();
+
+$docs_found = 0;
+while ($docs_found < 3) {
+ if ($cursor->valid()) {
+ $doc = $cursor->current();
+ echo json_encode($doc), PHP_EOL;
+ $docs_found++;
+ }
+ $cursor->next();
+}
+// end-tailable
diff --git a/source/includes/read/distinct.php b/source/includes/read/distinct.php
new file mode 100644
index 00000000..92745a3c
--- /dev/null
+++ b/source/includes/read/distinct.php
@@ -0,0 +1,40 @@
+sample_restaurants->restaurants;
+// end-db-coll
+
+// Retrieves distinct values of the "borough" field
+// start-distinct
+$results = $collection->distinct('borough', []);
+foreach ($results as $value) {
+ echo json_encode($value), PHP_EOL;
+}
+// end-distinct
+
+// Retrieves distinct "borough" field values for documents with a "cuisine" value of "Italian"
+// start-distinct-with-query
+$results = $collection->distinct('borough', ['cuisine' => 'Italian']);
+foreach ($results as $value) {
+ echo json_encode($value), PHP_EOL;
+}
+// end-distinct-with-query
+
+// Retrieves distinct "name" field values for documents matching the "borough" and "cuisine" fields query
+// and attaches a comment to the operation
+// start-distinct-with-comment
+$query = ['borough' => 'Bronx', 'cuisine' => 'Pizza'];
+$options = ['comment' => 'Bronx pizza restaurants'];
+$results = $collection->distinct('name', $query, $options);
+
+foreach ($results as $value) {
+ echo json_encode($value), PHP_EOL;
+}
+// end-distinct-with-comment
+
diff --git a/source/includes/read/limit-skip-sort.php b/source/includes/read/limit-skip-sort.php
new file mode 100644
index 00000000..433a6e6b
--- /dev/null
+++ b/source/includes/read/limit-skip-sort.php
@@ -0,0 +1,76 @@
+sample_restaurants->restaurants;
+// end-db-coll
+
+// Retrieves 5 documents that have a "cuisine" value of "Italian"
+// start-limit
+$cursor = $collection->find(
+ ['cuisine' => 'Italian'],
+ ['limit' => 5]
+);
+
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-limit
+
+// Retrieves documents with a "cuisine" value of "Italian" and sorts in ascending "name" order
+// start-sort
+$cursor = $collection->find(
+ ['cuisine' => 'Italian'],
+ ['sort' => ['name' => 1]]
+);
+
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-sort
+
+// Retrieves documents with a "borough" value of "Manhattan" but skips the first 10 results
+// start-skip
+$cursor = $collection->find(
+ ['borough' => 'Manhattan'],
+ ['skip' => 10]
+);
+
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-skip
+
+// Retrieves 5 documents with a "cuisine" value of "Italian", skips the first 10 results,
+// and sorts by ascending "name" order
+// start-limit-sort-skip
+$options = [
+ 'sort' => ['name' => 1],
+ 'limit' => 5,
+ 'skip' => 10,
+];
+
+$cursor = $collection->find(['cuisine' => 'Italian'], $options);
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-limit-sort-skip
+
+// Returns documents with a "cuisine" value of "Hawaiian" as arrays
+// start-return-type
+$options = [
+ 'typeMap' => [
+ 'root' => 'array',
+ 'document' => 'array'
+ ]
+];
+
+$cursor = $collection->find(['cuisine' => 'Hawaiian'], $options);
+foreach ($cursor as $doc) {
+ print_r($doc) . PHP_EOL;
+}
+// end-return-type
diff --git a/source/includes/read/project.php b/source/includes/read/project.php
new file mode 100644
index 00000000..c601402f
--- /dev/null
+++ b/source/includes/read/project.php
@@ -0,0 +1,59 @@
+sample_restaurants->restaurants;
+// end-db-coll
+
+// Retrieves documents matching the "name" field query and projects their "name", "cuisine", and "borough" values
+// start-project-include
+$options = [
+ 'projection' => [
+ 'name' => 1,
+ 'cuisine' => 1,
+ 'borough' => 1,
+ ],
+];
+
+$cursor = $collection->find(['name' => 'Emerald Pub'], $options);
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-project-include
+
+// Retrieves documents matching the "name" field query
+// and projects their "name", "cuisine", and "borough" values while excluding the "_id" values
+// start-project-include-without-id
+$options = [
+ 'projection' => [
+ '_id' => 0,
+ 'name' => 1,
+ 'cuisine' => 1,
+ 'borough' => 1,
+ ],
+];
+
+$cursor = $collection->find(['name' => 'Emerald Pub'], $options);
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-project-include-without-id
+
+// Retrieves documents matching the "name" field query and excludes their "grades" and "address" values when printing
+// start-project-exclude
+$options = [
+ 'projection' => [
+ 'grades' => 0,
+ 'address' => 0,
+ ],
+];
+
+$cursor = $collection->find(['name' => 'Emerald Pub'], $options);
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-project-exclude
diff --git a/source/includes/read/retrieve.php b/source/includes/read/retrieve.php
new file mode 100644
index 00000000..27765c96
--- /dev/null
+++ b/source/includes/read/retrieve.php
@@ -0,0 +1,39 @@
+sample_training->companies;
+// end-db-coll
+
+// Finds one document with a "name" value of "LinkedIn"
+// start-find-one
+$document = $collection->findOne(['name' => 'LinkedIn']);
+echo json_encode($document), PHP_EOL;
+// end-find-one
+
+// Finds documents with a "founded_year" value of 1970
+// start-find-many
+$results = $collection->find(['founded_year' => 1970]);
+// end-find-many
+
+// Prints documents with a "founded_year" value of 1970
+// start-cursor
+foreach ($results as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-cursor
+
+// Finds and prints up to 5 documents with a "number_of_employees" value of 1000
+// start-modify
+$results = $collection->find(
+ ['number_of_employees' => 1000],
+ ['limit' => 5]
+);
+
+foreach ($results as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-modify
diff --git a/source/includes/read/specify-queries.php b/source/includes/read/specify-queries.php
new file mode 100644
index 00000000..27ce4ebd
--- /dev/null
+++ b/source/includes/read/specify-queries.php
@@ -0,0 +1,108 @@
+';
+$client = new Client($uri);
+$collection = $client->db->fruits;
+
+// Inserts documents representing fruits
+$fruits = [
+ [
+ '_id' => 1,
+ 'name' => 'apples',
+ 'qty' => 5,
+ 'rating' => 3,
+ 'color' => 'red',
+ 'type' => ['fuji', 'honeycrisp']
+ ],
+ [
+ '_id' => 2,
+ 'name' => 'bananas',
+ 'qty' => 7,
+ 'rating' => 4,
+ 'color' => 'yellow',
+ 'type' => ['cavendish']
+ ],
+ [
+ '_id' => 3,
+ 'name' => 'oranges',
+ 'qty' => 6,
+ 'rating' => 2,
+ 'type' => ['naval', 'mandarin']
+ ],
+ [
+ '_id' => 4,
+ 'name' => 'pineapples',
+ 'qty' => 3,
+ 'rating' => 5,
+ 'color' => 'yellow'
+ ]
+];
+
+$result = $collection->insertMany($fruits);
+// end-setup
+
+// Retrieves documents in which the "color" value is "yellow"
+// start-find-exact
+$cursor = $collection->find(['color' => 'yellow']);
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-find-exact
+
+// Retrieves all documents in the collection
+// start-find-all
+$cursor = $collection->find([]);
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-find-all
+
+// Retrieves and prints documents in which the "rating" value is greater than 2
+// start-find-comparison
+$cursor = $collection->find(['rating' => ['$gt' => 2]]);
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-find-comparison
+
+// Retrieves and prints documents that match one or both query filters
+// start-find-logical
+$cursor = $collection->find([
+ '$or' => [
+ ['qty' => ['$gt' => 5]],
+ ['color' => 'yellow']
+ ]
+]);
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-find-logical
+
+// Retrieves and prints documents in which the "type" array has 2 elements
+// start-find-array
+$cursor = $collection->find(['type' => ['$size' => 2]]);
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-find-array
+
+// Retrieves and prints documents that have a "color" field
+// start-find-element
+$cursor = $collection->find(['color' => ['$exists' => true]]);
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-find-element
+
+// Retrieves and prints documents in which the "name" value has at least two consecutive "p" characters
+// start-find-evaluation
+$cursor = $collection->find(['name' => ['$regex' => 'p{2,}']]);
+foreach ($cursor as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-find-evaluation
diff --git a/source/includes/usage-examples/connect-code-examples.php b/source/includes/usage-examples/connect-code-examples.php
new file mode 100644
index 00000000..cc994df0
--- /dev/null
+++ b/source/includes/usage-examples/connect-code-examples.php
@@ -0,0 +1,177 @@
+';
+$client = new MongoDB\Client($uri);
+// end-atlas
+
+// Connects to a replica set using client options
+// start-replica-set-client
+$client = new MongoDB\Client(
+ 'mongodb://:/',
+ ['replicaSet' => ''],
+);
+// end-replica-set-client
+
+// Connects to a replica set using a connection URI parameter
+// start-replica-set-uri
+$uri = 'mongodb://:/?replicaSet=';
+$client = new MongoDB\Client($uri);
+// end-replica-set-uri
+
+// Connects to a MongoDB deployment and enables TLS using client
+// options
+// start-enable-tls-client
+$client = new MongoDB\Client(
+ 'mongodb://:/',
+ ['tls' => true],
+);
+// end-enable-tls-client
+
+// Connects to a MongoDB deployment and enables TLS using connection URI
+// parameters
+// start-enable-tls-uri
+$uri = 'mongodb://:/?tls=true';
+$client = new MongoDB\Client($uri);
+// end-enable-tls-uri
+
+// Connects to a MongoDB deployment, enables TLS, and specifies the path to
+// a CA file using client options
+// start-ca-file-client
+$client = new MongoDB\Client(
+ 'mongodb://:/',
+ ['tls' => true, 'tlsCAFile' => '/path/to/ca.pem'],
+);
+// end-ca-file-client
+
+// Connects to a MongoDB deployment, enables TLS, and specifies the path to
+// a CA file using connection URI parameters
+// start-ca-file-uri
+$uri = 'mongodb://:/?tls=true&tlsCAFile=/path/to/ca.pem';
+$client = new MongoDB\Client($uri);
+// end-ca-file-uri
+
+// Connects to a MongoDB deployment, enables TLS, and prevents OCSP endpoint checks
+// using client options
+// start-disable-ocsp-client
+$client = new MongoDB\Client(
+ 'mongodb://:/',
+ ['tls' => true, 'tlsDisableOCSPEndpointCheck' => true],
+);
+// end-disable-ocsp-client
+
+// Connects to a MongoDB deployment, enables TLS, and prevents OCSP endpoint checks
+// using connection URI parameters
+// start-disable-ocsp-uri
+$uri = 'mongodb://:/?tls=true&tlsDisableOCSPEndpointCheck=true';
+$client = new MongoDB\Client($uri);
+// end-disable-ocsp-uri
+
+// Connects to a TLS-enabled deployment and instructs the driver to check the
+// server certificate against a CRL
+// start-crl
+$client = new MongoDB\Client(
+ 'mongodb://:/',
+ ['tls' => true],
+ ['crl_file' => '/path/to/file.pem'],
+);
+// end-crl
+
+// Presents a client certificate to prove identity
+// using client options
+// start-client-cert-client
+$client = new MongoDB\Client(
+ 'mongodb://:/',
+ ['tls' => true, 'tlsCertificateKeyFile' => '/path/to/client.pem'],
+);
+// end-client-cert-client
+
+// Presents a client certificate to prove identity
+// using connection URI parameters
+// start-client-cert-uri
+$uri = 'mongodb://:/?tls=true&tlsCertificateKeyFile=/path/to/client.pem';
+$client = new MongoDB\Client($uri);
+// end-client-cert-uri
+
+// Specifies the password for a client certificate using client options
+// start-key-file-client
+$client = new MongoDB\Client(
+ 'mongodb://:/',
+ [
+ 'tls' => true,
+ 'tlsCertificateKeyFile' => '/path/to/client.pem',
+ 'tlsCertificateKeyFilePassword' => ''
+ ],
+);
+// end-key-file-client
+
+// Specifies the password for a client certificate using connection URI parameters
+// start-key-file-uri
+$uri = 'mongodb://:/?tls=true&tlsCertificateKeyFile=/path/to/client.pem&tlsCertificateKeyFilePassword=';
+$client = new MongoDB\Client($uri);
+// end-key-file-uri
+
+// Connects to a TLS-enabled deployment and disables server certificate verification
+// using client options
+// start-insecure-tls-client
+$client = new MongoDB\Client(
+ 'mongodb://:/',
+ ['tls' => true, 'tlsInsecure' => true],
+);
+// end-insecure-tls-client
+
+// Connects to a TLS-enabled deployment and disables server certificate verification
+// using connection URI parameters
+// start-insecure-tls-uri
+$uri = 'mongodb://:/?tls=true&tlsInsecure=true';
+$client = new MongoDB\Client($uri);
+// end-insecure-tls-uri
+
+// Disables certificate validation using client options
+// start-disable-cert-client
+$client = new MongoDB\Client(
+ 'mongodb://:/',
+ ['tls' => true, 'tlsAllowInvalidCertificates' => true],
+);
+// end-disable-cert-client
+
+// Disables certificate validation using connection URI parameters
+// start-disable-cert-uri
+$uri = 'mongodb://:/?tls=true&tlsAllowInvalidCertificates=true';
+$client = new MongoDB\Client($uri);
+// end-disable-cert-uri
+
+// Connects to a TLS-enabled deployment and disables hostname verification
+// using client options
+// start-disable-hostname-client
+$client = new MongoDB\Client(
+ 'mongodb://:/',
+ ['tls' => true, 'tlsAllowInvalidHostnames' => true],
+);
+// end-disable-hostname-client
+
+// Connects to a TLS-enabled deployment and disables hostname verification
+// using connection URI parameters
+// start-disable-hostname-uri
+$uri = 'mongodb://:/?tls=true&tlsAllowInvalidHostnames=true';
+$client = new MongoDB\Client($uri);
+// end-disable-hostname-uri
+
+// Connects to a MongoDB deployment and enables the stable API
+// start-stable-api
+$driverOptions = ['serverApi' => new MongoDB\Driver\ServerApi('1')];
+$client = new MongoDB\Client(
+ 'mongodb://:/',
+ [],
+ $driverOptions,
+);
+// end-stable-api
diff --git a/source/includes/usage-examples/connect-sample-app.php b/source/includes/usage-examples/connect-sample-app.php
new file mode 100644
index 00000000..d89319ff
--- /dev/null
+++ b/source/includes/usage-examples/connect-sample-app.php
@@ -0,0 +1,14 @@
+test->command(['ping' => 1]);
+ echo 'Successfully pinged the MongoDB server.', PHP_EOL;
+} catch (MongoDB\Driver\Exception\RuntimeException $e) {
+ printf("Failed to ping the MongoDB server: %s\n", $e->getMessage());
+}
diff --git a/source/includes/usage-examples/index-code-examples.php b/source/includes/usage-examples/index-code-examples.php
new file mode 100644
index 00000000..779e3a4e
--- /dev/null
+++ b/source/includes/usage-examples/index-code-examples.php
@@ -0,0 +1,101 @@
+sample_db;
+$collection = $database->sample_coll;
+
+// start-to-json
+function toJSON(object $document): string
+{
+ return MongoDB\BSON\Document::fromPHP($document)->toRelaxedExtendedJSON();
+}
+// end-to-json
+
+// start-single-field
+$indexName = $collection->createIndex(['' => 1]);
+// end-single-field
+
+// start-compound
+$indexName = $collection->createIndex(
+ ['' => 1, '' => 1]
+);
+// end-compound
+
+// start-multikey
+$indexName = $collection->createIndex(['' => 1]);
+// end-multikey
+
+// start-search-create
+$indexName = $collection->createSearchIndex(
+ ['mappings' => ['dynamic' => true]],
+ ['name' => '']
+);
+// end-search-create
+
+// start-search-list
+foreach ($collection->listSearchIndexes() as $indexInfo) {
+ echo toJSON($indexInfo), PHP_EOL;
+}
+// end-search-list
+
+// start-search-update
+$collection->updateSearchIndex(
+ '',
+ ['mappings' => [
+ 'dynamic' => false,
+ 'fields' => [
+ '' => [
+ 'type' => 'string',
+ 'analyzer' => 'lucene.standard'
+ ]
+ ]
+ ]]
+ );
+// end-search-update
+
+// start-search-delete
+$collection->dropSearchIndex('');
+// end-search-delete
+
+// start-text
+$indexName = $collection->createIndex(['' => 'text']);
+// end-text
+
+// start-geo
+$indexName = $collection->createIndex(
+ [ '' => '2dsphere']
+);
+// end-geo
+
+// start-unique
+$indexName = $collection->createIndex(['' => 1], ['unique' => true]);
+// end-unique
+
+// start-wildcard
+$indexName = $collection->createIndex(['$**' => 1]);
+// end-wildcard
+
+// start-clustered
+$options = [
+ 'clusteredIndex' => [
+ 'key' => ['_id' => 1],
+ 'unique' => true
+ ]
+];
+
+$database->createCollection('', $options);
+// end-clustered
+
+// start-list
+foreach ($collection->listIndexes() as $indexInfo) {
+ echo $indexInfo;
+}
+// end-list
+
+// start-remove
+$collection->dropIndex('');
+// end-remove
\ No newline at end of file
diff --git a/source/includes/usage-examples/read-code-examples.php b/source/includes/usage-examples/read-code-examples.php
new file mode 100644
index 00000000..d0db63b9
--- /dev/null
+++ b/source/includes/usage-examples/read-code-examples.php
@@ -0,0 +1,67 @@
+sample_mflix->movies;
+
+// Find One
+// start-find-one
+$document = $collection->findOne(['year' => 1994]);
+echo json_encode($document), PHP_EOL;
+// end-find-one
+
+// Find Multiple
+// start-find-multiple
+$resultsMultiple = $collection->find(['year' => 1970]);
+foreach ($resultsMultiple as $doc) {
+ echo json_encode($doc), PHP_EOL;
+}
+// end-find-multiple
+
+// Count Document
+// start-count
+$result = $collection->countDocuments([]);
+echo 'Number of documents: ', $result;
+// end-count
+
+// Count Specific Documents
+// start-count-specific
+$result = $collection->countDocuments(['year' => 2010]);
+echo 'Number of companies founded in 2010: ', $result;
+// end-count-specific
+
+// Estimated Count
+// start-count-estimate
+$result = $collection->estimatedDocumentCount();
+echo 'Estimated number of documents: ', $result;
+// end-count-estimate
+
+// Distinct Values
+// start-distinct
+$results = $collection->distinct('year');
+foreach ($results as $value) {
+ echo json_encode($value), PHP_EOL;
+}
+// end-distinct
+
+// Data Changes
+// start-change-stream
+$changeStream = $collection->watch();
+
+for ($changeStream->rewind(); true; $changeStream->next()) {
+ if ( ! $changeStream->valid()) {
+ continue;
+ }
+ $event = $changeStream->current();
+ echo toJSON($event), PHP_EOL;
+
+ if ($event['operationType'] === 'invalidate') {
+ break;
+ }
+}
+// end-change-stream
diff --git a/source/includes/usage-examples/sample-app-intro.rst b/source/includes/usage-examples/sample-app-intro.rst
new file mode 100644
index 00000000..a17549fe
--- /dev/null
+++ b/source/includes/usage-examples/sample-app-intro.rst
@@ -0,0 +1,12 @@
+Sample Application
+~~~~~~~~~~~~~~~~~~
+
+You can use the following sample application to test the code examples on this
+page. To use the sample application, perform the following steps:
+
+1. Ensure you have the {+php-library+} installed in your project. To learn more
+ about installing the {+php-library+}, see the
+ :ref:`Download and Install ` guide.
+#. Copy the following code and paste it into a new ``.php`` file.
+#. Copy a code example from this page and paste it on the specified
+ lines in the file.
diff --git a/source/includes/usage-examples/sample-app.php b/source/includes/usage-examples/sample-app.php
new file mode 100644
index 00000000..f9d2cb83
--- /dev/null
+++ b/source/includes/usage-examples/sample-app.php
@@ -0,0 +1,12 @@
+selectCollection('', '');
+
+// Start example code here
+
+// End example code here
diff --git a/source/includes/usage-examples/write-code-examples.php b/source/includes/usage-examples/write-code-examples.php
new file mode 100644
index 00000000..8e508822
--- /dev/null
+++ b/source/includes/usage-examples/write-code-examples.php
@@ -0,0 +1,116 @@
+db->coll;
+
+// Inserts one document that stores the specified values
+// start-insert-one
+$result = $collection->insertOne([
+ '' => '',
+ '' => '',
+]);
+// end-insert-one
+
+// Inserts multiple documents that store the specified values
+// start-insert-multiple
+$result = $collection->insertMany(
+ [
+ '' => '',
+ '' => '',
+ ],
+ [
+ '' => '',
+ '' => '',
+ ],
+);
+// end-insert-multiple
+
+// Updates a document that matches the specified criteria
+// start-update-one
+$result = $collection->updateOne(
+ ['' => ''],
+ ['$set' => ['' => '']],
+);
+// end-update-one
+
+// Updates all documents that match the specified criteria
+// start-update-multiple
+$result = $collection->updateMany(
+ ['' => ''],
+ ['$set' => ['' => '']],
+);
+// end-update-multiple
+
+// start-replace-one
+$result = $collection->replaceOne(
+ ['' => ''],
+ [
+ '' => '',
+ '' => '',
+ ],
+);
+// end-replace-one
+
+// Deletes a document that matches the specified criteria
+// start-delete-one
+$result = $collection->deleteOne(['' => '']);
+// end-delete-one
+
+// Deletes all documents that match the specified criteria
+// start-delete-multiple
+$result = $collection->deleteMany(['' => '']);
+// end-delete-multiple
+
+// Runs a bulk operation based on the instructions in each array entry
+// start-bulk-write
+$result = $collection->bulkWrite(
+ [
+ [
+ 'insertOne' => [
+ ['' => ''],
+ ],
+ ],
+ [
+ 'replaceOne' => [
+ ['' => ''],
+ [
+ '' => '',
+ '' => '',
+ ],
+ ],
+ ],
+ [
+ 'updateOne' => [
+ ['' => ''],
+ ['$set' => ['' => '']],
+ ],
+ ],
+ [
+ 'updateMany' => [
+ ['' => ''],
+ ['$set' => ['' => '']],
+ ],
+ ],
+ [
+ 'deleteOne' => [
+ ['' => ''],
+ ],
+ ],
+ [
+ 'deleteMany' => [
+ ['' => ''],
+ ],
+ ],
+ ]
+);
+// end-bulk-write
+
+// Stores a file in a GridFS bucket and writes data to the file
+// start-gridfs-upload
+$bucket = $client->selectDatabase('')->selectGridFSBucket();
+$stream = $bucket->openUploadStream('');
+fwrite($stream, '');
+fclose($stream);
+// end-gridfs-upload
diff --git a/source/includes/write/bulk-write.php b/source/includes/write/bulk-write.php
new file mode 100644
index 00000000..a3543a22
--- /dev/null
+++ b/source/includes/write/bulk-write.php
@@ -0,0 +1,57 @@
+sample_restaurants->restaurants;
+// end-db-coll
+
+// start-run-bulk
+$result = $collection->bulkWrite(
+ [
+ [
+ 'insertOne' => [
+ ['name' => 'Mongo\'s Deli'],
+ ['cuisine' => 'Sandwiches'],
+ ['borough' => 'Manhattan'],
+ ['restaurant_id' => '1234'],
+ ],
+ ],
+ [
+ 'updateOne' => [
+ ['name' => 'Mongo\'s Deli'],
+ ['$set' => ['cuisine' => 'Sandwiches and Salads']],
+ ],
+ ],
+ [
+ 'deleteMany' => [
+ ['borough' => 'Manhattan'],
+ ],
+ ],
+ ]
+);
+// end-run-bulk
+
+// start-bulk-options
+$result = $collection->bulkWrite(
+ [
+ [
+ 'insertOne' => [
+ ['name' => 'Mongo\'s Pizza'],
+ ['cuisine' => 'Italian'],
+ ['borough' => 'Queens'],
+ ['restaurant_id' => '5678'],
+ ],
+ ],
+ [
+ 'deleteOne' => [
+ ['restaurant_id' => '5678'],
+ ],
+ ],
+ ],
+ ['ordered' => false]
+);
+// end-bulk-options
diff --git a/source/includes/write/delete.php b/source/includes/write/delete.php
new file mode 100644
index 00000000..bab197a6
--- /dev/null
+++ b/source/includes/write/delete.php
@@ -0,0 +1,34 @@
+sample_restaurants->restaurants;
+// end-db-coll
+
+// Deletes a document that has a "name" value of "Ready Penny Inn"
+// start-delete-one
+$collection->deleteOne(['name' => 'Ready Penny Inn']);
+// end-delete-one
+
+// Deletes documents that have a "borough" value of "Brooklyn"
+// start-delete-many
+$collection->deleteMany(['borough' => 'Brooklyn']);
+// end-delete-many
+
+// Deletes matching documents and attaches a comment to the operation
+// start-delete-options
+$collection->deleteMany(
+ ['name' => new MongoDB\BSON\Regex('Mongo')],
+ ['comment' => 'Deleting Mongo restaurants'],
+);
+// end-delete-options
+
+// Deletes and prints the number of documents that have a "cuisine" value of "Greek"
+// start-delete-count
+$result = $collection->deleteMany(['cuisine' => 'Greek']);
+echo 'Deleted documents: ', $result->getDeletedCount(), PHP_EOL;
+// end-delete-count
+
diff --git a/source/includes/write/gridfs.php b/source/includes/write/gridfs.php
new file mode 100644
index 00000000..bb94ce63
--- /dev/null
+++ b/source/includes/write/gridfs.php
@@ -0,0 +1,91 @@
+toRelaxedExtendedJSON();
+}
+// end-to-json
+
+// Creates a GridFS bucket or references an existing one
+// start-create-bucket
+$bucket = $client->db->selectGridFSBucket();
+// end-create-bucket
+
+// Creates or references a GridFS bucket with a custom name
+// start-create-custom-bucket
+$custom_bucket = $client->db->selectGridFSBucket(
+ ['bucketName' => 'myCustomBucket']
+);
+// end-create-custom-bucket
+
+// Uploads a file called "my_file" to the GridFS bucket and writes data to it
+// start-open-upload-stream
+$stream = $bucket->openUploadStream('my_file', [
+ 'metadata' => ['contentType' => 'text/plain']
+]);
+fwrite($stream, 'Data to store');
+fclose($stream);
+// end-open-upload-stream
+
+// Uploads data to a stream, then writes the stream to a GridFS file
+// start-upload-from-stream
+$file = fopen('/path/to/input_file', 'rb');
+$bucket->uploadFromStream('new_file', $file);
+// end-upload-from-stream
+
+// Prints information about each file in the bucket
+// start-retrieve-file-info
+$files = $bucket->find();
+foreach ($files as $file_doc) {
+ echo toJSON($file_doc), PHP_EOL;
+}
+// end-retrieve-file-info
+
+// Downloads the "my_file" file from the GridFS bucket and prints its contents
+// start-open-download-stream-name
+$stream = $bucket->openDownloadStreamByName('my_file');
+$contents = stream_get_contents($stream);
+echo $contents, PHP_EOL;
+fclose($stream);
+// end-open-download-stream-name
+
+// Downloads a file from the GridFS bucket by referencing its ObjectId value
+// start-download-files-id
+$stream = $bucket->openDownloadStream(new ObjectId('66e0a5487c880f844c0a32b1'));
+$contents = stream_get_contents($stream);
+fclose($stream);
+// end-download-files-id
+
+// Downloads the original "my_file" file from the GridFS bucket
+// start-download-file-revision
+$stream = $bucket->openDownloadStreamByName('my_file', ['revision' => 0]);
+$contents = stream_get_contents($stream);
+fclose($stream);
+// end-download-file-revision
+
+// Downloads an entire GridFS file to a download stream
+// start-download-to-stream
+$file = fopen('/path/to/output_file', 'wb');
+$bucket->downloadToStream(
+ new ObjectId('66e0a5487c880f844c0a32b1'),
+ $file,
+);
+// end-download-to-stream
+
+// Renames a file from the GridFS bucket with the specified ObjectId
+// start-rename-files
+$bucket->rename(new ObjectId('66e0a5487c880f844c0a32b1'), 'new_file_name');
+// end-rename-files
+
+// Deletes a file from the GridFS bucket with the specified ObjectId
+// start-delete-files
+$bucket->delete(new ObjectId('66e0a5487c880f844c0a32b1'));
+// end-delete-files
diff --git a/source/includes/write/insert.php b/source/includes/write/insert.php
new file mode 100644
index 00000000..3561a65e
--- /dev/null
+++ b/source/includes/write/insert.php
@@ -0,0 +1,37 @@
+sample_restaurants->restaurants;
+// end-db-coll
+
+// Inserts a document that stores a "name" value of "Mongo's Burgers" into the collection
+// start-insert-one
+$result = $collection->insertOne(['name' => 'Mongo\'s Burgers']);
+// end-insert-one
+
+// Inserts documents representing restaurants into the collection
+// start-insert-many
+$restaurants = [
+ ['name' => 'Mongo\'s Burgers'],
+ ['name' => 'Mongo\'s Pizza']
+];
+
+$result = $collection->insertMany($restaurants);
+// end-insert-many
+
+// Inserts multiple documents and instructs the insert operation to skip document-level validation
+// start-modify
+$docs = [
+ ['name' => 'Mongo\'s Burgers'],
+ ['name' => 'Mongo\'s Pizza'],
+ ['name' => 'Mongo\'s Tacos']
+];
+
+$result = $collection->insertMany($docs, ['bypassDocumentValidation' => true]);
+// end-modify
+
diff --git a/source/includes/write/replace.php b/source/includes/write/replace.php
new file mode 100644
index 00000000..7c14c806
--- /dev/null
+++ b/source/includes/write/replace.php
@@ -0,0 +1,42 @@
+sample_restaurants->restaurants;
+// end-db-coll
+
+// start-replace-one
+$replace_document = [
+ 'name' => 'Mongo\'s Pizza',
+ 'cuisine' => 'Pizza',
+ 'address' => [
+ 'street' => '123 Pizza St',
+ 'zipCode' => '10003',
+ ],
+ 'borough' => 'Manhattan'
+];
+
+$result = $collection->replaceOne(['name' => 'Pizza Town'], $replace_document);
+echo 'Modified documents: ', $result->getModifiedCount();
+// end-replace-one
+
+// start-replace-options
+$replace_document = [
+ 'name' => 'Food World',
+ 'cuisine' => 'Mixed',
+ 'address' => [
+ 'street' => '123 Food St',
+ 'zipCode' => '10003',
+ ],
+ 'borough' => 'Manhattan'
+];
+
+$result = $collection->replaceOne(
+ ['name' => 'Food Town'],
+ $replace_document,
+ ['upsert' => true]
+);
+// end-replace-options
diff --git a/source/includes/write/run-command.php b/source/includes/write/run-command.php
new file mode 100644
index 00000000..d074c337
--- /dev/null
+++ b/source/includes/write/run-command.php
@@ -0,0 +1,32 @@
+selectDatabase('myDB');
+$cursor = $database->command(['hello' => 1]);
+// end-hello
+
+// start-readpref
+$readPref = new MongoDB\Driver\ReadPreference('primaryPreferred');
+$cursor = $database->command(
+ ['hello' => 1],
+ ['readPreference' => $readPref]
+);
+// end-readpref
+
+// start-runcommand
+$database = $client->accounts;
+$command = ['dbStats' => 1];
+
+// dbStats returns a single document
+$cursor = $database->command($command);
+
+// Print the first document in the cursor
+echo json_encode($cursor->toArray()[0]), PHP_EOL;
+// end-runcommand
diff --git a/source/includes/write/transaction.php b/source/includes/write/transaction.php
new file mode 100644
index 00000000..eaa73394
--- /dev/null
+++ b/source/includes/write/transaction.php
@@ -0,0 +1,58 @@
+bank->receipts;
+$checking = $client->bank->checking_accounts;
+$saving = $client->bank->saving_accounts;
+
+$accountId = "5678";
+$transferAmount = 1000.0;
+
+$callback = function (MongoDB\Driver\Session $session) use (
+ $checking,
+ $saving,
+ $receipts,
+ $accountId,
+ $transferAmount
+): void {
+ $checking->updateOne(
+ ["account_id" => $accountId],
+ ['$inc' => ["balance" => -$transferAmount]],
+ ["session" => $session]
+ );
+
+ $saving->updateOne(
+ ["account_id" => $accountId],
+ ['$inc' => ["balance" => $transferAmount]],
+ ["session" => $session]
+ );
+
+ $summary = sprintf('SAVINGS +%1$u CHECKING -%1$u', $transferAmount);
+
+ $receipts->insertOne(
+ [
+ "account_id" => $accountId,
+ "summary" => $summary,
+ "timestamp" => new MongoDB\BSON\UTCDateTime(),
+ ],
+ ["session" => $session]
+ );
+
+ echo "Successfully performed transaction!", PHP_EOL;
+ echo "Summary: ", $summary, PHP_EOL;
+};
+// end-callback
+
+// begin-txn
+$session = $client->startSession();
+
+try {
+ MongoDB\with_transaction($session, $callback);
+} catch (MongoDB\Driver\Exception\RuntimeException $e) {
+ echo "Caught exception: ", $e->getMessage(), PHP_EOL;
+}
+// end-txn
\ No newline at end of file
diff --git a/source/includes/write/update.php b/source/includes/write/update.php
new file mode 100644
index 00000000..cd43f60c
--- /dev/null
+++ b/source/includes/write/update.php
@@ -0,0 +1,45 @@
+sample_restaurants->restaurants;
+// end-db-coll
+
+// Updates the "name" value of a document from "Bagels N Buns" to "2 Bagels 2 Buns"
+// start-update-one
+$result = $collection->updateOne(
+ ['name' => 'Bagels N Buns'],
+ ['$set' => ['name' => '2 Bagels 2 Buns']]
+);
+// end-update-one
+
+// Updates the "cuisine" value of documents from "Pizza" to "Pasta"
+// start-update-many
+$result = $collection->updateMany(
+ ['cuisine' => 'Pizza'],
+ ['$set' => ['cuisine' => 'Pasta']]
+);
+// end-update-many
+
+// Updates the "borough" value of matching documents and inserts a document if none match
+// start-update-options
+$result = $collection->updateMany(
+ ['borough' => 'Manhattan'],
+ ['$set' => ['borough' => 'Manhattan (north)']],
+ ['upsert' => true]
+);
+// end-update-options
+
+// Updates the "name" value of matching documents and prints the number of updates
+// start-update-result
+$result = $collection->updateMany(
+ ['name' => 'Dunkin\' Donuts'],
+ ['$set' => ['name' => 'Dunkin\'']]
+);
+echo 'Modified documents: ', $result->getModifiedCount();
+// end-update-result
+
diff --git a/source/index.txt b/source/index.txt
index 1c5c6e72..5627d911 100644
--- a/source/index.txt
+++ b/source/index.txt
@@ -10,68 +10,128 @@ MongoDB PHP Library
.. toctree::
:titlesonly:
- Installation
- /tutorial
+ Get Started
+ /connect
+ /databases-collections
+ /read
+ /write
+ /read-write-pref
+ /run-command
+ /aggregation
+ /indexes
+ /monitoring
+ /security
+ /data-formats
+ /compatibility
+ /whats-new
/upgrade
- /reference
FAQ
- /whats-new
+ /reference
+
+Overview
+--------
-The |php-library| provides a high-level abstraction around the lower-level
+Welcome to the documentation site for the official {+php-library+}.
+
+The {+library-short+} provides a high-level abstraction around the lower-level
:php:`mongodb extension `.
-The ``mongodb`` extension provides a limited API to connect to the database and
-execute generic commands, queries, and write operations. In contrast, the
-|php-library| provides a full-featured API and models client, database, and
-collection objects. Each of those classes provide various helper methods for
-performing operations in context. For example, :phpclass:`MongoDB\Collection`
-implements methods for executing CRUD operations and managing indexes on the
-collection, among other things.
+The ``mongodb`` extension provides a limited API to connect to a MongoDB
+database and execute generic commands, queries, and write operations. In
+contrast, the {+library-short+} provides a full-featured API and models client,
+database, and collection objects. If you are developing a PHP application with
+MongoDB, consider using the {+library-short+} instead of the extension alone.
+
+Get Started
+-----------
+
+Learn how to install the library and extension, establish a connection to MongoDB,
+and begin working with data in the :ref:`php-get-started` tutorial.
+
+Connect to MongoDB
+------------------
+
+Learn how to create and configure a connection to a MongoDB deployment
+in the :ref:`php-connect` section.
+
+Databases and Collections
+-------------------------
+
+Learn how to use the {+library-short+} to work with MongoDB databases and collections
+in the :ref:`php-databases-collections` section.
+
+Read Data from MongoDB
+----------------------
+
+Learn how you can retrieve data from MongoDB in the :ref:`php-read` section.
+
+Write Data to MongoDB
+---------------------
+
+Learn how you can write data to MongoDB in the :ref:`php-write` section.
+
+Specify How CRUD Operations Run on Replica Sets
+-----------------------------------------------
+
+Learn how to configure settings for read and write operations on replica
+sets in the :ref:`php-read-write-pref` section.
+
+Run a Database Command
+----------------------
-If you are developing a PHP application with MongoDB, you should consider using
-the |php-library| instead of the extension alone.
+Learn how to run a database command in the :ref:`php-run-command` section.
-New to the PHP Library?
------------------------
+Transform Your Data with Aggregation
+------------------------------------
-If you have some experience with MongoDB but are new to the PHP library, the
-following pages should help you get started:
+Learn how to use the {+library-short+} to perform aggregation operations in the
+:ref:`php-aggregation` section.
-- :doc:`/tutorial/install-php-library`
+Optimize Queries with Indexes
+-----------------------------
-- :doc:`/tutorial/connecting`
+Learn how to work with common types of indexes in the :ref:`php-indexes`
+section.
-- :doc:`/tutorial/crud`
+Monitoring
+----------
-- :doc:`/tutorial/commands`
+Learn how to monitor change events in the :ref:`php-monitoring`
+section.
-- :doc:`/tutorial/gridfs`
+Secure Your Data
+----------------
-- :doc:`/tutorial/modeling-bson-data`
+Learn about ways you can authenticate your application and encrypt your data in
+the :ref:`php-security` section.
-- :doc:`/reference/bson`
+Specialized Data Formats
+------------------------
-Code examples can be found in the ``examples`` directory in the source code.
+Learn how to work with specialized data formats and custom types in the
+:ref:`php-data-formats` section.
-If you have previously worked with the legacy ``mongo`` extension, it will be
-helpful to review the :doc:`/upgrade` for a summary of API changes between the
-old driver and this library.
+Compatibility
+-------------
-You can view changes introduced in each version release of the
-{+php-library+} in the :ref:`php-lib-whats-new` section.
+See compatibility tables showing the recommended {+library-short+} version to use for
+specific PHP and {+mdb-server+} versions in the :ref:`php-compatibility` section.
-New to MongoDB?
----------------
+What's New
+----------
-If you are a new MongoDB user, the following links should help you become more
-familiar with MongoDB and introduce some of the concepts and terms you will
-encounter in the library documentation:
+Learn about new features and changes in each version in the :ref:``
+section.
-- :manual:`Introduction to MongoDB `
-- :manual:`Databases and Collections `
+Upgrade Library Versions
+------------------------
+
+Learn what changes you must make to your application to upgrade library and
+extension versions in the :ref:`php-upgrade` section.
-- :manual:`Documents ` and
- :manual:`BSON Types `
+FAQ
+---
-- :manual:`MongoDB CRUD Operations `
+See answers to commonly asked questions about the {+library-short+} in the
+the :ref:`php-faq` section.
\ No newline at end of file
diff --git a/source/indexes.txt b/source/indexes.txt
new file mode 100644
index 00000000..2e6d5ccf
--- /dev/null
+++ b/source/indexes.txt
@@ -0,0 +1,292 @@
+.. _php-indexes:
+
+=================================
+Optimize Queries by Using Indexes
+=================================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :description: Learn how to use indexes by using the MongoDB PHP Library.
+ :keywords: query, optimization, efficiency, usage example, code example
+
+.. toctree::
+ :titlesonly:
+ :maxdepth: 1
+
+ /indexes/index-mgmt
+ /indexes/single-field-index
+ /indexes/compound-index
+ /indexes/multikey-index
+ /indexes/atlas-search-index
+
+Overview
+--------
+
+On this page, you can see copyable code examples that show how to manage
+different types of indexes by using the {+php-library+}.
+
+.. tip::
+
+ To learn more about working with indexes, see the :ref:`php-index-mgmt`
+ guide. To learn more about any of the indexes shown on this page, see the link
+ provided in each section.
+
+To use an example from this page, copy the code example into the
+:ref:`sample application ` or your own application.
+Make sure to set the ``MONGODB_URI`` environment variable to the
+connection string for your MongoDB deployment, and replace the
+```` and ```` placeholders with values for your
+target namespace.
+
+.. _php-index-sample:
+
+.. include:: /includes/usage-examples/sample-app-intro.rst
+
+.. literalinclude:: /includes/usage-examples/sample-app.php
+ :language: php
+ :copyable:
+ :linenos:
+ :emphasize-lines: 10-12
+
+Some examples use the ``toJSON()`` function to represent change events, which are BSON
+documents, as Extended JSON. To use this function, paste the following code into your
+application file:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :language: php
+ :dedent:
+ :start-after: start-to-json
+ :end-before: end-to-json
+
+Single Field Index
+------------------
+
+The following example creates an ascending index on the specified field:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-single-field
+ :end-before: end-single-field
+ :language: php
+ :copyable:
+ :dedent:
+
+To learn more about single field indexes, see the
+:ref:`php-single-field-index` guide.
+
+Compound Index
+--------------
+
+The following example creates a compound index of two ascending indexes
+on the specified fields:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-compound
+ :end-before: end-compound
+ :language: php
+ :copyable:
+ :dedent:
+
+To learn more about compound indexes, see the :ref:`php-compound-index`
+guide.
+
+Multikey Index
+--------------
+
+The following example creates an ascending multikey index on the
+specified array-valued field:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-multikey
+ :end-before: end-multikey
+ :language: php
+ :copyable:
+ :dedent:
+
+To learn more about multikey indexes, see the :ref:`php-multikey-index`
+guide.
+
+Geospatial Index
+----------------
+
+The following example creates a 2dsphere index on the specified field
+that has GeoJSON object values:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-geo
+ :end-before: end-geo
+ :language: php
+ :copyable:
+ :dedent:
+
+To learn more about the GeoJSON data type, see :manual:`GeoJSON Objects
+` in the {+mdb-server+} manual.
+
+.. TODO: To learn more about geospatial indexes, see the :ref:`php-geospatial-index`
+.. guide.
+
+Unique Index
+------------
+
+The following example creates an ascending unique index on the specified
+field:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-unique
+ :end-before: end-unique
+ :language: php
+ :copyable:
+ :dedent:
+
+.. TODO: To learn more about unique indexes, see the :ref:`php-unique-index`
+.. guide.
+
+Wildcard Index
+--------------
+
+The following example creates an ascending wildcard index on the
+collection:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-wildcard
+ :end-before: end-wildcard
+ :language: php
+ :copyable:
+ :dedent:
+
+.. TODO: To learn more about wildcard indexes, see the :ref:`php-wildcard-index`
+.. guide.
+
+Clustered Index
+---------------
+
+You can create a clustered index when creating a new collection in a
+specified database. The following example creates a new collection with an
+ascending clustered index on the ``_id`` field:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-clustered
+ :end-before: end-clustered
+ :language: php
+ :copyable:
+ :dedent:
+
+.. TODO: To learn more about clustered indexes, see the :ref:`php-clustered-index`
+.. guide.
+
+Text Index
+----------
+
+The following example creates a text index on the specified string field:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-text
+ :end-before: end-text
+ :language: php
+ :copyable:
+ :dedent:
+
+.. TODO: To learn more about text indexes, see the :ref:`php-text-index`
+.. guide.
+
+List Indexes
+------------
+
+The following example prints a list of indexes in the
+specified collection:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-list
+ :end-before: end-list
+ :language: php
+ :copyable:
+ :dedent:
+
+Delete an Index
+---------------
+
+The following example deletes an index with the specified name:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-remove
+ :end-before: end-remove
+ :language: php
+ :copyable:
+ :dedent:
+
+To learn more about deleting indexes, see :ref:`php-remove-idx`
+in the Index Considerations and Management guide.
+
+Atlas Search Index Management
+-----------------------------
+
+The following sections contain code examples that describe how to manage
+:atlas:`Atlas Search indexes `.
+
+.. note:: Atlas Search Index Management is Asynchronous
+
+ The {+php-library+} manages Atlas Search indexes asynchronously. The
+ library methods described in the following sections return the server
+ response immediately, but the changes to your Search indexes take
+ place in the background and might not complete until some time later.
+
+To learn more about Atlas Search indexes, see the :ref:`php-atlas-search-index`
+guide.
+
+Create Search Index
+~~~~~~~~~~~~~~~~~~~
+
+The following example creates an Atlas Search index on the specified field:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-search-create
+ :end-before: end-search-create
+ :language: php
+ :copyable:
+ :dedent:
+
+List Search Indexes
+~~~~~~~~~~~~~~~~~~~
+
+The following example prints a list of Atlas Search indexes in the
+specified collection:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-search-list
+ :end-before: end-search-list
+ :language: php
+ :copyable:
+ :dedent:
+
+Update Search Indexes
+~~~~~~~~~~~~~~~~~~~~~
+
+The following example updates an existing Atlas Search index with the specified
+new index definition:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-search-update
+ :end-before: end-search-update
+ :language: php
+ :copyable:
+ :dedent:
+
+Delete Search Indexes
+~~~~~~~~~~~~~~~~~~~~~
+
+The following example deletes an Atlas Search index with the specified name:
+
+.. literalinclude:: /includes/usage-examples/index-code-examples.php
+ :start-after: start-search-delete
+ :end-before: end-search-delete
+ :language: php
+ :copyable:
+ :dedent:
diff --git a/source/indexes/atlas-search-index.txt b/source/indexes/atlas-search-index.txt
new file mode 100644
index 00000000..eb8762aa
--- /dev/null
+++ b/source/indexes/atlas-search-index.txt
@@ -0,0 +1,149 @@
+.. _php-atlas-search-index:
+
+====================
+Atlas Search Indexes
+====================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 1
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: index, query, text search, efficiency
+
+Overview
+--------
+
+The MongoDB Atlas Search feature enables you to perform full-text
+searches on collections hosted on Atlas. Before you can perform Atlas
+Search queries, you must create indexes that specify which
+fields to index and how they are indexed.
+
+To learn more about Atlas Search, see the :atlas:`Atlas Search Overview
+`.
+
+You can use the following methods on a ``MongoDB\Collection`` instance
+to manage your Atlas Search indexes:
+
+- ``MongoDB\Collection::createSearchIndex()``
+- ``MongoDB\Collection::createSearchIndexes()``
+- ``MongoDB\Collection::listSearchIndexes()``
+- ``MongoDB\Collection::updateSearchIndex()``
+- ``MongoDB\Collection::dropSearchIndex()``
+
+.. note:: Atlas Search Index Management is Asynchronous
+
+ The {+php-library+} manages Atlas Search indexes asynchronously. The
+ library methods described in the following sections return the server
+ response immediately, but the changes to your Search indexes take
+ place in the background and might not complete until some time later.
+
+The following sections provide code examples that demonstrate how to use
+each Atlas Search index management method.
+
+.. _php-atlas-search-index-create:
+
+Create a Search Index
+---------------------
+
+You can use the ``createSearchIndex()`` method to create a single Atlas
+Search index on a collection, or the ``createSearchIndexes()`` method to
+create multiple indexes simultaneously.
+
+The following code example shows how to create a single Atlas Search
+index:
+
+.. literalinclude:: /includes/indexes/indexes.php
+ :language: php
+ :start-after: start-create-search-index
+ :end-before: end-create-search-index
+
+The following code example shows how to create multiple Atlas Search
+indexes:
+
+.. literalinclude:: /includes/indexes/indexes.php
+ :language: php
+ :start-after: start-create-search-indexes
+ :end-before: end-create-search-indexes
+
+After you create a Search index, you can perform Atlas Search queries on
+your collection. To learn more, see :atlas:`Create and Run Atlas Search
+Queries ` in the Atlas documentation.
+
+.. _php-atlas-search-index-list:
+
+List Search Indexes
+-------------------
+
+You can use the ``listSearchIndexes()`` method to return an array of the
+Atlas Search indexes on a collection:
+
+.. literalinclude:: /includes/indexes/indexes.php
+ :language: php
+ :dedent:
+ :start-after: start-list-search-indexes
+ :end-before: end-list-search-indexes
+
+.. _php-atlas-search-index-update:
+
+Update a Search Index
+---------------------
+
+You can use the ``updateSearchIndex()``
+method to update an Atlas Search index. You can use this method to
+change the name of a Search index or change the configuration of the
+index.
+
+The following code shows how to update a search index to use a simple
+analyzer on the ``title`` field:
+
+.. literalinclude:: /includes/indexes/indexes.php
+ :language: php
+ :dedent:
+ :start-after: start-update-search-indexes
+ :end-before: end-update-search-indexes
+
+.. _php-atlas-search-index-drop:
+
+Delete a Search Index
+---------------------
+
+You can use the ``dropSearchIndex()`` method to remove an Atlas Search
+index from a collection.
+
+The following code shows how to delete the Atlas Search index named
+``mySearchIdx``:
+
+.. literalinclude:: /includes/indexes/indexes.php
+ :language: php
+ :dedent:
+ :start-after: start-delete-search-index
+ :end-before: end-delete-search-index
+
+Additional Information
+----------------------
+
+To view runnable examples that demonstrate how to manage indexes, see
+:ref:`php-indexes`.
+
+To view tutorials that explain how to use the Atlas Search feature, see
+:atlas:`Get Started with Atlas Search ` in the
+Atlas documentation.
+
+API Documentation
+~~~~~~~~~~~~~~~~~
+
+To learn more about any of the methods discussed in this guide, see the
+following API documentation:
+
+- :phpmethod:`MongoDB\Collection::createSearchIndex()`
+- :phpmethod:`MongoDB\Collection::createSearchIndexes()`
+- :phpmethod:`MongoDB\Collection::listSearchIndexes()`
+- :phpmethod:`MongoDB\Collection::updateSearchIndex()`
+- :phpmethod:`MongoDB\Collection::dropSearchIndex()`
diff --git a/source/indexes/compound-index.txt b/source/indexes/compound-index.txt
new file mode 100644
index 00000000..130eb8a2
--- /dev/null
+++ b/source/indexes/compound-index.txt
@@ -0,0 +1,86 @@
+.. _php-compound-index:
+
+================
+Compound Indexes
+================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: index, query, optimization, efficiency
+
+Overview
+--------
+
+**Compound indexes** hold references to multiple
+fields within a collection's documents, improving query and sort
+performance. You can create a compound index on a collection
+by using the ``MongoDB\Collection::createIndex()`` method and the same
+syntax that you use to create :ref:`single field indexes
+`.
+
+Sample Data
+~~~~~~~~~~~
+
+The examples in this guide use the ``movies`` collection in the
+``sample_mflix`` database from the :atlas:`Atlas sample datasets
+`. To learn how to create a free MongoDB Atlas cluster and
+load the sample datasets, see the :atlas:`Get Started with Atlas
+` guide.
+
+Create a Compound Index
+-----------------------
+
+Use the ``MongoDB\Collection::createIndex()`` method to create a
+compound index. The following example creates an index in ascending
+order on the ``title`` and ``year`` fields:
+
+.. literalinclude:: /includes/indexes/indexes.php
+ :start-after: start-index-compound
+ :end-before: end-index-compound
+ :language: php
+ :copyable:
+ :dedent:
+
+The following is an example of a query that is covered by the index
+created in the preceding code example:
+
+.. io-code-block::
+ :copyable: true
+
+ .. input:: /includes/indexes/indexes.php
+ :start-after: start-compound-query
+ :end-before: end-compound-query
+ :language: php
+ :dedent:
+
+ .. output::
+ :visible: false
+
+ {"_id":...,"title":"Before Sunrise",...,"year":1995,...}
+
+Additional Information
+----------------------
+
+To learn more about compound indexes, see :manual:`Compound
+Indexes ` in the {+mdb-server+} manual.
+
+To view runnable examples that demonstrate how to manage indexes, see
+:ref:`php-indexes`.
+
+API Documentation
+~~~~~~~~~~~~~~~~~
+
+To learn more about any of the methods discussed in this guide, see the following API
+documentation:
+
+- :phpmethod:`MongoDB\Collection::createIndex()`
+- :phpmethod:`MongoDB\Collection::findOne()`
diff --git a/source/indexes/index-mgmt.txt b/source/indexes/index-mgmt.txt
new file mode 100644
index 00000000..b56b8fa2
--- /dev/null
+++ b/source/indexes/index-mgmt.txt
@@ -0,0 +1,141 @@
+.. _php-index-mgmt:
+
+===================================
+Index Considerations and Management
+===================================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: query, optimization, efficiency
+
+Overview
+--------
+
+In this guide, you can learn about using **indexes** to improve the
+efficiency of your queries and add functionality to querying and
+storing documents.
+
+Without a relevant index, MongoDB scans every document in a collection
+to find the documents that match a query. These collection scans are
+slow and can negatively affect the performance of your application.
+However, if the appropriate index exists, MongoDB can use the index to
+reduce the number of documents to inspect.
+
+Operational Considerations
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To improve query performance, build indexes on fields that appear often in
+your application's queries or operations that return sorted results. Each
+index that you add consumes disk space and memory, so we recommend
+that you track memory and disk usage when doing capacity planning. In addition,
+when a write operation updates an indexed field, MongoDB updates the related
+index, which can negatively impact performance for write operations.
+
+You can use :manual:`wildcard indexes ` in your
+MongoDB application to query against fields whose names are not known in
+advance or are arbitrary. Wildcard indexes are *not* designed to replace
+workload-based index planning.
+
+To learn more about designing your data model and choosing
+indexes, see the :manual:`Indexes
+` section of the Operational
+Factors and Data Models guide in the {+mdb-server+} manual.
+
+Sample Data
+~~~~~~~~~~~
+
+The examples in this guide use the ``movies`` collection in the
+``sample_mflix`` database from the :atlas:`Atlas sample datasets
+`. To learn how to create a free MongoDB Atlas cluster and
+load the sample datasets, see the :atlas:`Get Started with Atlas
+` guide.
+
+Create an Index
+---------------
+
+MongoDB supports several index types to help query your data.
+The following pages describe different index types and provide sample
+code to programmatically create each type of index.
+
+- :ref:`php-single-field-index`
+- :ref:`php-compound-index`
+- :ref:`php-multikey-index`
+- :ref:`php-atlas-search-index`
+
+List Indexes
+------------
+
+You can retrieve a list of indexes on a collection by calling the
+``MongoDB\Collection::listIndexes()`` method:
+
+.. literalinclude:: /includes/indexes/indexes.php
+ :language: php
+ :start-after: start-list-indexes
+ :end-before: end-list-indexes
+ :dedent:
+
+.. _php-remove-idx:
+
+Remove an Index
+---------------
+
+You can remove any unused index except the default unique index on the
+``_id`` field.
+
+The following sections provide examples that show how to remove one or
+more indexes from a collection.
+
+Delete a Single Index
+~~~~~~~~~~~~~~~~~~~~~
+
+Pass the name of an index to the ``MongoDB\Collection::dropIndex()``
+method to remove an index from a collection.
+
+The following example removes the ``'_title_'`` index from the
+``movies`` collection:
+
+.. literalinclude:: /includes/indexes/indexes.php
+ :language: php
+ :start-after: start-remove-index
+ :end-before: end-remove-index
+ :dedent:
+
+.. note::
+
+ You cannot remove a single field from a compound index. You must
+ drop the entire index and create a new one to update the indexed
+ fields.
+
+Delete All Indexes
+~~~~~~~~~~~~~~~~~~
+
+You can delete all indexes by calling the
+``MongoDB\Collection::dropIndexes()`` method on a collection:
+
+.. literalinclude:: /includes/indexes/indexes.php
+ :language: php
+ :start-after: start-remove-all-indexes
+ :end-before: end-remove-all-indexes
+ :dedent:
+
+The ``dropIndexes()`` method returns information about the number of
+indexes removed and a success message.
+
+API Documentation
+~~~~~~~~~~~~~~~~~
+
+To learn more about any of the methods or types discussed in this
+guide, see the following API documentation:
+
+- :phpmethod:`MongoDB\Collection::listIndexes()`
+- :phpmethod:`MongoDB\Collection::dropIndex()`
+- :phpmethod:`MongoDB\Collection::dropIndexes()`
diff --git a/source/indexes/multikey-index.txt b/source/indexes/multikey-index.txt
new file mode 100644
index 00000000..b3ef21d9
--- /dev/null
+++ b/source/indexes/multikey-index.txt
@@ -0,0 +1,89 @@
+.. _php-multikey-index:
+
+================
+Multikey Indexes
+================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: index, query, optimization, efficiency
+
+Overview
+--------
+
+**Multikey indexes** are indexes that improve the performance of queries
+on array-valued fields. You can create a multikey index on a collection
+by using the ``MongoDB\Collection::createIndex()`` method and the same
+syntax that you use to create :ref:`single field
+` or compound indexes.
+
+Sample Data
+~~~~~~~~~~~
+
+The examples in this guide use the ``movies`` collection in the
+``sample_mflix`` database from the :atlas:`Atlas sample datasets
+`. To learn how to create a free MongoDB Atlas cluster and
+load the sample datasets, see the :atlas:`Get Started with Atlas
+` guide.
+
+Create a Multikey Index
+-----------------------
+
+Use the ``MongoDB\Collection::createIndex()`` method to create a
+multikey index. The following example creates an index in ascending
+order on the array-valued ``cast`` field:
+
+.. literalinclude:: /includes/indexes/indexes.php
+ :start-after: start-multikey
+ :end-before: end-multikey
+ :language: php
+ :copyable:
+ :dedent:
+
+The following is an example of a query that is covered by the index
+created in the preceding code example:
+
+.. io-code-block::
+ :copyable: true
+
+ .. input:: /includes/indexes/indexes.php
+ :start-after: start-index-array-query
+ :end-before: end-index-array-query
+ :language: php
+ :dedent:
+
+ .. output::
+ :visible: false
+
+ {"_id":...,"title":"Holi",...,"cast":["Ashutosh Gowariker",
+ "Aamir Khan","Rahul Ranade","Sanjeev Gandhi"],...}
+
+Additional Information
+----------------------
+
+Multikey indexes behave differently from other indexes in terms of query
+coverage, index bound computation, and sort behavior. To learn more
+about the behavior and limitations of multikey indexes, see
+:manual:`Multikey Indexes ` in the {+mdb-server+}
+manual.
+
+To view runnable examples that demonstrate how to manage indexes, see
+:ref:`php-indexes`.
+
+API Documentation
+~~~~~~~~~~~~~~~~~
+
+To learn more about any of the methods discussed in this guide, see the following API
+documentation:
+
+- :phpmethod:`MongoDB\Collection::createIndex()`
+- :phpmethod:`MongoDB\Collection::findOne()`
diff --git a/source/indexes/single-field-index.txt b/source/indexes/single-field-index.txt
new file mode 100644
index 00000000..acffcb7a
--- /dev/null
+++ b/source/indexes/single-field-index.txt
@@ -0,0 +1,99 @@
+.. _php-single-field-index:
+
+====================
+Single Field Indexes
+====================
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecol
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: index, query, optimization, efficiency
+
+Overview
+--------
+
+Single field indexes are indexes with a reference to a single field of a
+document in a collection. These indexes improve single field query and
+sort performance. They also support :manual:`TTL Indexes `
+that automatically remove documents from a collection after a certain
+amount of time or at a specified clock time.
+
+When creating a single-field index, you must specify the following
+details:
+
+- The field on which to create the index
+- The sort order for the indexed values as either ascending or
+ descending
+
+.. note::
+
+ The default ``_id_`` index is an example of a single-field index.
+ This index is automatically created on the ``_id`` field when a new
+ collection is created.
+
+Sample Data
+~~~~~~~~~~~
+
+The examples in this guide use the ``movies`` collection in the
+``sample_mflix`` database from the :atlas:`Atlas sample datasets
+`. To learn how to create a free MongoDB Atlas cluster and
+load the sample datasets, see the :atlas:`Get Started with Atlas
+` guide.
+
+Create Single-Field Index
+-------------------------
+
+Use the ``MongoDB\Collection::createIndex()`` method to create a single
+field index. The following example creates an index in ascending order on the
+``title`` field:
+
+.. literalinclude:: /includes/indexes/indexes.php
+ :start-after: start-index-single
+ :end-before: end-index-single
+ :language: php
+ :copyable:
+ :dedent:
+
+The following is an example of a query that is covered by the index
+created in the preceding code example:
+
+.. io-code-block::
+ :copyable: true
+
+ .. input:: /includes/indexes/indexes.php
+ :start-after: start-index-single-query
+ :end-before: end-index-single-query
+ :language: php
+ :dedent:
+
+ .. output::
+ :visible: false
+
+ {"_id":...,"plot":"A musical comedy duo...",
+ "genres":["Musical"],...,"title":"Sweethearts",...}
+
+Additional Information
+----------------------
+
+To view runnable examples that demonstrate how to manage indexes, see
+:ref:`php-indexes`.
+
+To learn more about single field indexes, see :manual:`Single Field
+Indexes ` in the {+mdb-server+} manual.
+
+API Documentation
+~~~~~~~~~~~~~~~~~
+
+To learn more about any of the methods discussed in this guide, see the
+following API documentation:
+
+- :phpmethod:`MongoDB\Collection::createIndex()`
+- :phpmethod:`MongoDB\Collection::findOne()`
diff --git a/source/monitoring.txt b/source/monitoring.txt
new file mode 100644
index 00000000..5322004f
--- /dev/null
+++ b/source/monitoring.txt
@@ -0,0 +1,21 @@
+.. _php-monitoring:
+
+========================
+Monitor Your Application
+========================
+
+.. toctree::
+ :caption: Monitoring categories
+
+ /monitoring/cluster-monitoring
+
+.. /monitoring/command-monitoring
+.. /monitoring/connection-monitoring
+
+- :ref:`Cluster Monitoring `: Monitor changes
+ in your cluster configuration
+
+.. TODO - :ref:`Command Monitoring `: monitor command
+.. execution
+.. - :ref:`Connection Pool Monitoring `:
+.. monitor changes in the connection pool
\ No newline at end of file
diff --git a/source/monitoring/cluster-monitoring.txt b/source/monitoring/cluster-monitoring.txt
new file mode 100644
index 00000000..0093aa47
--- /dev/null
+++ b/source/monitoring/cluster-monitoring.txt
@@ -0,0 +1,163 @@
+.. _php-cluster-monitoring:
+
+==================
+Cluster Monitoring
+==================
+
+.. facet::
+ :name: genre
+ :values: reference
+
+.. meta::
+ :keywords: code example, server, topology
+
+.. contents:: On this page
+ :local:
+ :backlinks: none
+ :depth: 2
+ :class: singlecols
+
+Overview
+--------
+
+This guide shows you how to use the {+php-library+} to monitor server
+discovery and monitoring (SDAM) events in a MongoDB instance, replica
+set, or sharded cluster. These events occur when there are any changes
+in the state of the MongoDB instance or cluster that you are connected
+to.
+
+You might use information about SDAM events in your application to
+understand cluster changes, assess cluster health, or perform capacity
+planning.
+
+.. _php-subscribe-sdam:
+
+Subscribe to Events
+-------------------
+
+You can access details about SDAM events by subscribing to them
+in your application. To subscribe to an event, create a class that
+implements the ``MongoDB\Driver\Monitoring\SDAMSubscriber`` interface,
+then use the ``MongoDB\Client::addSubscriber()`` method to register the
+event subscriber with your ``MongoDB\Client`` instance.
+
+The following code creates the ``MySubscriber`` class, which implements
+the ``SDAMSubscriber`` interface. The class is defined with a method to
+output a message when a ``ServerOpeningEvent`` is generated by the
+server:
+
+.. literalinclude:: /includes/monitoring/sdam.php
+ :start-after: start-mysubscriber
+ :end-before: end-mysubscriber
+ :language: php
+ :copyable:
+ :dedent:
+
+.. note::
+
+ As shown in the preceding code, you must implement all the methods
+ of the ``SDAMSubscriber`` interface, even for events you are not subscribing to.
+ The example defines the extra methods as empty so that the
+ application does not output any messages for those events.
+
+Then, use the ``addSubscriber()`` method to register ``MySubscriber``
+with the client, as shown in the following code:
+
+.. literalinclude:: /includes/monitoring/sdam.php
+ :start-after: start-add-sub
+ :end-before: end-add-sub
+ :language: php
+ :copyable:
+ :dedent:
+
+When you run the application, your subscriber records the SDAM event and
+outputs messages such as the following:
+
+.. code-block:: none
+ :copyable: false
+
+ Server opening on ac-rmuag0v-shard-00-00.gh0qg50.mongodb.net:27017
+ Server opening on ac-rmuag0v-shard-00-01.gh0qg50.mongodb.net:27017
+ Server opening on ac-rmuag0v-shard-00-02.gh0qg50.mongodb.net:27017
+
+Event Descriptions
+------------------
+
+You can subscribe to SDAM events by implementing the corresponding
+method from the ``SDAMSubscriber`` interface. The following table
+provides the name of each SDAM event, linked to the class's API
+documentation, and a description of when the event is published:
+
+.. list-table::
+ :widths: 35 65
+ :header-rows: 1
+
+ * - Event Type
+ - Description
+
+ * - :php:`ServerChangedEvent `
+ - Created when the server description changes, such as the server's
+ type changing from secondary to primary.
+
+ * - :php:`ServerOpeningEvent `
+ - Created when a new server is added to the topology.
+
+ * - :php:`ServerClosedEvent `
+ - Created when an existing server is removed from the topology.
+
+ * - :php:`TopologyChangedEvent `
+ - Created when the topology description changes, such as when there
+ is an election of a new primary.
+
+ * - :php:`TopologyOpeningEvent