diff --git a/config/redirects b/config/redirects index 3ca604de..5a8393bd 100644 --- a/config/redirects +++ b/config/redirects @@ -92,4 +92,5 @@ raw: ${prefix}/stable -> ${base}/current/ [*-master]: ${prefix}/${version}/aggregation/vector-search/ -> ${base}/${version}/vector-search/ [*-master]: ${prefix}/${version}/monitoring/ -> ${base}/${version}/monitoring-logging/ [*-master]: ${prefix}/${version}/read/ -> ${base}/${version}/crud/ -[*-master]: ${prefix}/${version}/write/ -> ${base}/${version}/crud/ \ No newline at end of file +[*-master]: ${prefix}/${version}/write/ -> ${base}/${version}/crud/ +[*-master]: ${prefix}/${version}/faq/ -> ${base}/${version}/ \ No newline at end of file diff --git a/source/connect/client.txt b/source/connect/client.txt index 793c1027..51017c38 100644 --- a/source/connect/client.txt +++ b/source/connect/client.txt @@ -118,6 +118,67 @@ This example constructs a client and passes the following parameters: :language: php :copyable: true +Client Persistence +------------------ + +The ``libmongoc`` library and the {+extension-short+} handle connections +to a MongoDB deployment. When you construct a :phpclass:`MongoDB\Client` instance, the +{+library-short+} creates a :php:`MongoDB\Driver\Manager ` instance by using the +same connection string and options. The extension also uses those constructor +arguments to derive a hash key for persistent ``libmongoc`` clients. If +you previously persisted a ``libmongoc`` client by using a key, it is +reused. Otherwise, a new ``libmongoc`` client is created and persisted +for the lifetime of the PHP worker process. To learn more about +this process, see the :php:`{+extension-short+} documentation +`. + +Each ``libmongoc`` client maintains its own connections to the MongoDB deployment +and a view of its topology. When you reuse a persistent ``libmongoc`` client, the +{+library-short+} can avoid the overhead of establishing new connections and +rediscovering the topology. This approach generally improves performance and is +the driver's default behavior. + +Persistent ``libmongoc`` clients are not freed until the PHP worker process +ends. As a result, connections to a MongoDB deployment might remain open +after a ``MongoDB\Driver\Manager`` object goes out of scope. While this is +typically not an issue for applications that connect to one MongoDB deployment, +it might cause errors in the following situations: + +- PHP-FPM is configured with ``pm.max_requests=0`` so workers never respawn, and a + PHP application is deployed many times with small changes to its MongoDB + connection string or options. This could lead to an accumulation of ``libmongoc`` + client objects in each worker process. + +- An application occasionally connects to a separate MongoDB deployment in a + backend component where request latency is not the most important aspect. + +In the first case, restarting PHP-FPM as part of the application deployment +allows the application to release any unused ``libmongoc`` clients and still use +a persistent client for the latest connection string. + +The second case requires a different solution. Specifying ``true`` for the +``disableClientPersistence`` driver option instructs the {+library-short+} to +create a new ``libmongoc`` client and ensure it is freed when the corresponding +``MongoDB\Driver\Manager`` goes out of scope. + +The following code demonstrates how to set the +``disableClientPersistence`` option to ``true`` when creating a client: + +.. code-block:: php + :emphasize-lines: 5 + + true], + ); + +.. note:: + + If you disable client persistence, the {+library-short+} requires more + time to establish connections to the MongoDB deployment and discover its topology. + API Documentation ----------------- diff --git a/source/connect/connection-targets.txt b/source/connect/connection-targets.txt index 6a4668c7..be081222 100644 --- a/source/connect/connection-targets.txt +++ b/source/connect/connection-targets.txt @@ -124,6 +124,88 @@ DNS Service Discovery $uri = 'mongodb+srv:///'; +Server Selection Errors +----------------------- + +The following code shows possible server selection error +messages that your application might generate: + +.. code-block:: none + :copyable: false + + No suitable servers found (`serverSelectionTryOnce` set): + [connection refused calling hello on 'a.example.com:27017'] + [connection refused calling hello on 'b.example.com:27017'] + + No suitable servers found: `serverSelectionTimeoutMS` expired: + [socket timeout calling hello on 'example.com:27017'] + + No suitable servers found: `serverSelectionTimeoutMS` expired: + [connection timeout calling hello on 'a.example.com:27017'] + [connection timeout calling hello on 'b.example.com:27017'] + [TLS handshake failed: -9806 calling hello on 'c.example.com:27017'] + + No suitable servers found: `serverselectiontimeoutms` timed out: + [TLS handshake failed: certificate verify failed (64): IP address mismatch calling hello on 'a.example.com:27017'] + [TLS handshake failed: certificate verify failed (64): IP address mismatch calling hello on 'b.example.com:27017'] + +The {+extension-short+} usually represents these errors as +:php:`MongoDB\Driver\Exception\ConnectionTimeoutException ` +exceptions. However, the exception messages originate from +``libmongoc``, which is the underlying system library used by the extension. Since +these messages can take many forms, we recommend breaking down the structure of +the message so you can better diagnose errors in your application. + +Messages typically start with "No suitable servers found". The next part of +the message indicates *how* server selection failed. The extension +avoids a server selection loop and makes a single attempt by default, according to +the ``serverSelectionTryOnce`` connection string option. If the extension is +configured to use a loop, a message that includes the phrase "serverSelectionTimeoutMS expired" +indicates that you exhausted its time limit. + +The last component of the message tells us *why* server selection failed and +includes one or more errors directly from the topology scanner, which is the +service responsible for connecting to and monitoring each host. Any host that +previously experienced an error during monitoring will be included in this list. These +messages typically originate from low-level socket or TLS functions. + +The following list describes the possible meanings of common phrases in the last error message +component: + +- "Connection refused": The remote host might not be not listening on + the expected port. +- "Connection timeout": There might be a routing problem, a firewall error, or + a timeout due to latency. +- "Socket timeout": You likely established an initial connection that + was dropped or timed out due to latency. +- "TLS handshake failed": TLS or OCSP verification did not succeed, and you might + be using misconfigured TLS certificates. + +In the case of a connection failure, you can use the ``connect`` tool for +more troubleshooting information. This tool tries to connect to each host in a +connection string by using socket functions, and then attempts to interact with +data. If you used Composer to install the library, you can use the following command +to start the ``connect`` tool: + +.. code-block:: none + + php vendor/mongodb/mongodb/tools/connect.php + +If the server you are connecting to does not accept connections, the output +resembles the following code: + +.. code-block:: none + + Looking up MongoDB at + Found 1 host(s) in the URI. Will attempt to connect to each. + + Could not connect to :: Connection refused + +.. note:: + + The tool supports only the ``mongodb://`` URI schema. Using the + ``mongodb+srv`` scheme is not supported. + API Documentation ----------------- diff --git a/source/faq.txt b/source/faq.txt deleted file mode 100644 index 3b7a6edf..00000000 --- a/source/faq.txt +++ /dev/null @@ -1,250 +0,0 @@ -.. _php-faq: - -========================== -Frequently Asked Questions -========================== - -.. meta:: - :description: Find solutions to common PHP extension installation errors, connection handling, and server selection failures when using the MongoDB PHP library. - - -.. contents:: On this page - :local: - :backlinks: none - :depth: 2 - :class: singlecol - -Common Extension Installation Errors ------------------------------------- - -PHP Headers Not Found -~~~~~~~~~~~~~~~~~~~~~ - -For example: - -.. code-block:: none - - /private/tmp/pear/install/mongodb/php_phongo.c:24:10: fatal error: 'php.h' file not found - - #include - ^~~~~~~ - -This error indicates that PHP's build system cannot find the necessary headers. -All PHP extensions require headers in order to compile. Additionally, those -headers must correspond to the PHP runtime for which the extension will be used. -Generally, the ``phpize`` command (invoked by ``pecl``) will ensure that the -extension builds with the correct headers. - -Note that the mere presence of a PHP runtime does not mean that headers are -available. On various Linux distributions, headers are often published under a -separate ``php-dev`` or ``php-devel`` package. On macOS, the default PHP runtime -does not include headers and users typically need to install PHP (and headers) -via `Homebrew `_ in order to build an extension. - -Multiple PHP Runtimes Installed -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -If your system has multiple versions of PHP installed, each version will have -its own ``pecl`` and ``phpize`` commands. Additionally, each PHP runtime may -have separate ``php.ini`` files for each SAPI (e.g. FPM, CLI). If the extension -has been installed but is not available at runtime, double-check that you have -used the correct ``pecl`` command and have modified the appropriate ``php.ini`` -file(s). - -If there is any doubt about the ``php.ini`` file being used by a PHP runtime, -you should examine the output of :php:`phpinfo() ` for that particular -SAPI. Additionally, :php:`php_ini_loaded_file() ` and -:php:`php_ini_scanned_files() ` may be used to determine -exactly which INI files have been loaded by PHP. - -To debug issues with the extension not being loaded, you can use the -``detect-extension`` script provided in the tools directory. You can run this -script from the CLI or include it in a script accessible via your web server. -The tool will point out potential issues and installation instructions for your -system. Assuming you've installed the library through Composer, you can call the -script from the vendor directory: - -.. code-block:: none - - php vendor/mongodb/mongodb/tools/detect-extension.php - -If you want to check configuration for a web server SAPI, include the file in -a script accessible from the web server and open it in your browser. Remember to -wrap the script in ``
`` tags to properly format its output:
-
-.. code-block:: php
-
-   
- -Loading an Incompatible DLL on Windows -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Windows binaries are available for various combinations of PHP version, -thread safety (TS or NTS), and architecture (x86 or x64). Failure to select the -correct binary will result in an error when attempting to load the extension DLL -at runtime: - -.. code-block:: none - - PHP Warning: PHP Startup: Unable to load dynamic library 'mongodb' - -Ensure that you have downloaded a DLL that corresponds to the following PHP -runtime properties: - -- PHP version (``PHP_VERSION``) -- Thread safety (``PHP_ZTS``) -- Architecture (``PHP_INT_SIZE``) - -In addition to the aforementioned constants, these properties can also be -inferred from :php:`phpinfo() `. If your system has multiple PHP -runtimes installed, double-check that you are examining the ``phpinfo()`` output -for the correct environment. - -The aforementioned ``detect-extension`` script can also be used to determine the -appropriate DLL for your PHP environment. - -Connection Handling and Persistence ------------------------------------ - -Connections to the MongoDB deployment are handled by the ``libmongoc`` -library and the :php:`{+extension-short+} `. When you construct -a :phpclass:`MongoDB\Client` instance, the {+library-short+} creates a -:php:`MongoDB\Driver\Manager ` instance by using the -same connection string and options. The extension also uses those constructor -arguments to derive a hash key for persistent ``libmongoc`` clients. If -you previously persisted a ``libmongoc`` client by using a key, it is -reused. Otherwise, a new ``libmongoc`` client is created and persisted -for the lifetime of the PHP worker process. You can learn more about -this process in the :php:`{+extension-short+} documentation -`. - -Each ``libmongoc`` client maintains its own connections to the MongoDB deployment -and a view of its topology. When you reuse a persistent ``libmongoc`` client, the -{+library-short+} can avoid the overhead of establishing new connections and -rediscovering the topology. This approach generally improves performance and is -the driver's default behavior. - -Persistent ``libmongoc`` clients are not freed until the PHP worker process -ends. This means that connections to a MongoDB deployment might remain open -after a ``MongoDB\Driver\Manager`` object goes out of scope. While this is -typically not an issue for applications that connect to one MongoDB deployment, -it might be problematic in some situations, which are described in the -following list: - -- PHP-FPM is configured with ``pm.max_requests=0``, so that workers never respawn, and a - PHP application is deployed many times with small changes to its MongoDB - connection string or options. This could lead to an accumulation of ``libmongoc`` - client objects in each worker process. - -- An application occasionally connects to a separate MongoDB deployment in a - backend component where request latency is not the most important aspect. - -In the first case, restarting PHP-FPM as part of the application deployment -allows the application to release any unused ``libmongoc`` clients and still use -a persistent client for the latest connection string. - -The second case requires a different solution. Specifying ``true`` for the -``disableClientPersistence`` driver option instructs the {+library-short+} to -create a new ``libmongoc`` client and ensure it is freed when the corresponding -``MongoDB\Driver\Manager`` goes out of scope. - -The following code demonstrates how to set the -``disableClientPersistence`` option to ``true`` when creating a client: - -.. code-block:: php - :emphasize-lines: 6 - - true], - ); - -Use the ``disableClientPersistence`` driver option after careful -consideration, because opting out of client persistence requires more -time to establish connections to the MongoDB deployment and discover its -topology. - -Server Selection Failures -------------------------- - -The following are all examples of -:doc:`Server Selection ` failures: - -.. code-block:: none - - No suitable servers found (`serverSelectionTryOnce` set): - [connection refused calling hello on 'a.example.com:27017'] - [connection refused calling hello on 'b.example.com:27017'] - - No suitable servers found: `serverSelectionTimeoutMS` expired: - [socket timeout calling hello on 'example.com:27017'] - - No suitable servers found: `serverSelectionTimeoutMS` expired: - [connection timeout calling hello on 'a.example.com:27017'] - [connection timeout calling hello on 'b.example.com:27017'] - [TLS handshake failed: -9806 calling hello on 'c.example.com:27017'] - - No suitable servers found: `serverselectiontimeoutms` timed out: - [TLS handshake failed: certificate verify failed (64): IP address mismatch calling hello on 'a.example.com:27017'] - [TLS handshake failed: certificate verify failed (64): IP address mismatch calling hello on 'b.example.com:27017'] - -These errors typically manifest as a -:php:`MongoDB\Driver\Exception\ConnectionTimeoutException ` -exception from the extension. The actual exception messages originate from -libmongoc, which is the underlying system library used by the extension. Since -these messages can take many forms, it's helpful to break down the structure of -the message so you can better diagnose errors in your application. - -Messages will typically start with "No suitable servers found". The next part of -the message indicates *how* server selection failed. By default, the extension -avoids a server selection loop and instead makes a single attempt (according to -the ``serverSelectionTryOnce`` connection string option). If the extension is -configured to utilize a loop, a message like "serverSelectionTimeoutMS expired" -will tell us that we exhausted its time limit. - -The last component of the message tells us *why* server selection failed, and -includes one or more errors directly from the topology scanner, which is the -service responsible for connecting to and monitoring each host. Any host that -last experienced an error during monitoring will be included in this list. These -messages typically originate from low-level socket or TLS functions. - -The following is not meant to be exhaustive, but will hopefully point you in the -right direction for analyzing the contributing factor(s) for a server selection -failure: - -- "connection refused" likely indicates that the remote host is not listening on - the expected port. -- "connection timeout" could indicate a routing or firewall issue, or perhaps - a timeout due to latency. -- "socket timeout" suggests that a connection *was* established at some point - but was dropped or otherwise timed out due to latency. -- "TLS handshake failed" suggests something related to TLS or OCSP verification - and is sometimes indicative of misconfigured TLS certificates. - -In the case of a connection failure, you can use the ``connect`` tool to try and -receive more information. This tool attempts to connect to each host in a -connection string using socket functions to see if it is able to establish a -connection, send, and receive data. The tool takes the connection string to a -MongoDB deployment as its only argument. Assuming you've installed the library -through Composer, you would call the script from the vendor directory: - -.. code-block:: none - - php vendor/mongodb/mongodb/tools/connect.php mongodb://127.0.0.1:27017 - -In case the server does not accept connections, the output will look like this: - -.. code-block:: none - - Looking up MongoDB at mongodb://127.0.0.1:27017 - Found 1 host(s) in the URI. Will attempt to connect to each. - - Could not connect to 127.0.0.1:27017: Connection refused - -.. note:: - - The tool only supports the ``mongodb://`` URI schema. Using the - ``mongodb+srv`` scheme is not supported. diff --git a/source/get-started.txt b/source/get-started.txt index 007cbeb8..6b2e1038 100644 --- a/source/get-started.txt +++ b/source/get-started.txt @@ -341,8 +341,101 @@ In this tutorial, you created a PHP application that connects to a MongoDB deployment hosted on MongoDB Atlas and retrieves a document that matches a query. - Learn more about the {+php-library+} from the following resources: - Learn how to configure your MongoDB connection in the :ref:`php-connect` section. -- Learn how to perform read and write operations in the :ref:`php-crud-operations` section. \ No newline at end of file +- Learn how to perform read and write operations in the :ref:`php-crud-operations` section. + +Troubleshooting +--------------- + +This section addresses issues that you might encounter when installing the +{+library-short+} and its dependencies. + +PHP Headers Not Found +~~~~~~~~~~~~~~~~~~~~~ + +You might see a header file error that resembles the following code when installing +the {+library-short+}: + +.. code-block:: none + :copyable: false + + /private/tmp/pear/install/mongodb/php_phongo.c:24:10: fatal error: 'php.h' file not found + + #include + ^~~~~~~ + +This error indicates that PHP's build system cannot find the necessary headers. +All PHP extensions require headers in order to compile. Those headers +must correspond to the PHP runtime for which the extension will be used. +The ``phpize`` command, which is invoked by ``pecl`` and ``pie``, usually ensures that the +extension builds with the correct headers. + +If you install a PHP runtime, the corresponding headers are not always automatically +available. On many Linux distributions, headers are often published under a +separate ``php-dev`` or ``php-devel`` package. On macOS, the default PHP runtime +does not include headers. Users typically need to install PHP and its headers by using +`Homebrew `__. + +Multiple PHP Runtimes Installed +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +If your system has multiple versions of PHP installed, each version will have +its own ``pecl``, ``pie``, and ``phpize`` commands. Additionally, each PHP runtime may +have separate ``php.ini`` files for each server application programming interface (SAPI), +such as FPM and CLI. If you installed the extension but it is not available at runtime, +ensure that you use the correct ``pecl`` or ``pie`` command and modify the appropriate ``php.ini`` +file. + +To see which ``php.ini`` file a PHP runtime uses, +view the output of :php:`phpinfo() ` for that particular +SAPI. Additionally, you can use :php:`php_ini_loaded_file() ` and +:php:`php_ini_scanned_files() ` to determine +which INI files have been loaded by PHP. + +To debug issues when the extension is not loaded, you can use the +``detect-extension`` script provided in the tools directory. You can run this +script from the CLI or include it in a script accessible to your web server. +The tool finds potential issues and installation instructions for your +system. If you installed the library by using Composer, you can call the +script from the vendor directory as shown in the following code: + +.. code-block:: none + + php vendor/mongodb/mongodb/tools/detect-extension.php + +If you want to check configuration for a web server SAPI, include the file in +a script accessible from the web server and open it in your browser. Ensure that you +wrap the script in ``
`` tags to properly format its output as shown in the following code:
+
+.. code-block:: php
+
+   
+ +Loading an Incompatible DLL on Windows +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Windows binaries are available for several combinations of a PHP version, +thread safety setting (TS or NTS), and architecture type (x86 or x64). Failure to select the +correct binary causes an error when attempting to load the extension DLL +at runtime, as shown in the following sample output: + +.. code-block:: none + :copyable: false + + PHP Warning: PHP Startup: Unable to load dynamic library 'mongodb' + +Ensure that you have downloaded a DLL that corresponds to the following PHP +runtime properties: + +- PHP version (``PHP_VERSION``) +- Thread safety (``PHP_ZTS``) +- Architecture (``PHP_INT_SIZE``) + +In addition to the preceding constants, these properties can also be +inferred from :php:`phpinfo() `. If your system has multiple PHP +runtimes installed, view the ``phpinfo()`` output for the correct environment. + +You can also use the ``detect-extension`` script described in the previous section to determine the +correct DLL for your PHP environment. \ No newline at end of file diff --git a/source/index.txt b/source/index.txt index 67848f53..5befd559 100644 --- a/source/index.txt +++ b/source/index.txt @@ -26,7 +26,6 @@ MongoDB PHP Library Monitoring and Logging Security Reference - FAQ API Documentation Issues & Help @@ -118,12 +117,6 @@ Reference Learn more about {+library-short+} versions, compatibility, and upgrade considerations in the :ref:`Reference ` section. -FAQ ---- - -See answers to commonly asked questions about the {+library-short+} in the -the :ref:`php-faq` section. - Issues & Help -------------