Handling MongoDB PHP Errors
Rate this article
Welcome to this article about MongoDB error handling in PHP. Code samples and tutorials abound on the web , but for clarity's sake, they often don't show what to do with potential errors. Our goal here is to show you common mechanisms to deal with potential issues like connection loss, temporary inability to read/write, initialization failures, and more.
This article was written using PHP 8.1 and MongoDB 6.1.1 (serverless) with the PHP Extension and Library 1.15. As things may change in the future, you can refer to our official MongoDB PHP documentation.
- A MongoDB Atlas cluster with sample data loaded. We have MongoDB Atlas free tier clusters available to all.
- A web server with PHP and the MongoDB PHP driver installed. Ideally, follow our "Getting Set Up to Run PHP with MongoDB" guide.
- Alternatively, you can consider using PHP's built-in webserver, which can be simpler to set up and might avoid other web server environment variances.
We will refer to the MongoDB PHP Driver, which has two distinct components. First, there's the MongoDB PHP Extension, which is the system-level interface to MongoDB.
Secondly, there's the MongoDB PHP Library, a PHP library that is the application's interface to MongoDB. You can learn about the people behind our PHP driver in this excellent podcast episode.
Clone it from the Github repository to a local folder in the public section of your web server and website. You can use the command
1 git clone https://github.com/mongodb-developer/php-error-handling-sample
Go to the project's directory with the command
1 cd php-error-handling-sample
and run the command
1 composer install
Composer will download external libraries to the "vendor" directory (see the screenshot below). Note that Composer will check if the MongoDB PHP extension is installed, and will report an error if it is not.
Create an .env file containing your database user credentials in the same folder as index.php. Our previous tutorial describes how to do this in the "Securing Usernames and Passwords" section. The .env file is a simple text file formatted as follows:
MDB_USER=[user name]
MDB_PASS=[password]
MDB_PASS=[password]
In your web browser, navigate to
website-url/php-error-handling-sample/
, and index.php
will be executed.Upon execution, our code sample outputs a page like this, and there are various ways to induce errors to see how the various checks work by commenting/uncommenting lines in the source code.
Initially, developers run into system-level issues related to the PHP configuration and whether or not the MongoDB PHP driver is properly installed. That's especially true when your code is deployed on servers you don't control. Here are two common system-level runtime errors and how to check for them:
- Is the MongoDB extension installed and loaded?
- Is the MongoDB PHP Library available to your code?
There are many ways to check if the MongoDB PHP extension is installed and loaded and here are two in the article, while the others are in the the code file.
- You can call PHP's
extension_loaded()
function withmongodb
as the argument. It will return true or false. - You can call
class_exists()
to check for the existence of theMongoDB\Driver\Manager
class defined in the MongoDB PHP extension. - Call
phpversion('mongodb')
, which should return the MongoDB PHP extension version number on success and false on failure. - The MongoDB PHP Library also contains a detect-extension.php file which shows another way of detecting if the extension was loaded. This file is not part of the distribution but it is documented.
1 // MongoDB Extension check, Method #1 2 if ( extension_loaded('mongodb') ) { 3 echo(MSG_EXTENSION_LOADED_SUCCESS); 4 } else { 5 echo(MSG_EXTENSION_LOADED_FAIL); 6 } 7 8 // MongoDB Extension check, Method #2 9 if ( !class_exists('MongoDB\Driver\Manager') ) { 10 echo(MSG_EXTENSION_LOADED2_FAIL); 11 exit(); 12 } 13 else { 14 echo(MSG_EXTENSION_LOADED2_SUCCESS); 15 }
Failure for either means the MongoDB PHP extension has not been loaded properly and you should check your php.ini configuration and error logs, as this is a system configuration issue. Our Getting Set Up to Run PHP with MongoDB article provides debugging steps and tips which may help you.
Once the MongoDB PHP extension is up and running, the next thing to do is to check if the MongoDB PHP Library is available to your code. You are not obligated to use the library, but we highly recommend you do. It keeps things more abstract, so you focus on your app instead of the inner-workings of MongoDB.
Look for the
MongoDB\Client
class. If it's there, the library has been added to your project and is available at runtime.1 // MongoDB PHP Library check 2 if ( !class_exists('MongoDB\Client') ) { 3 echo(MSG_LIBRARY_MISSING); 4 exit(); 5 } 6 else { 7 echo(MSG_LIBRARY_PRESENT); 8 }
You can now instantiate a client with your connection string . (Here's how to find the Atlas connection string.)
The instantiation will fail if something is wrong with the connection string parsing or the driver cannot resolve the connection's SRV (DNS) record. Possible causes for SRV resolution failures include the IP address being rejected by the MongoDB cluster or network connection issues while checking the SRV.
1 // Fail if the MongoDB Extension is not configuired and loaded 2 // Fail if the connection URL is wrong 3 try { 4 // IMPORTANT: replace with YOUR server DNS name 5 $mdbserver = 'serverlessinstance0.owdak.mongodb.net'; 6 7 $client = new MongoDB\Client('mongodb+srv://'.$_ENV['MDB_USER'].':'.$_ENV['MDB_PASS'].'@'.$mdbserver.'/?retryWrites=true&w=majority'); 8 echo(MSG_CLIENT_SUCCESS); 9 // succeeds even if user/password is invalid 10 } 11 catch (\Exception $e) { 12 // Fails if the URL is malformed 13 // Fails without a SVR check 14 // fails if the IP is blocked by an ACL or firewall 15 echo(MSG_CLIENT_FAIL); 16 exit(); 17 }
Up to this point, the library has just constructed an internal driver manager, and no I/O to the cluster has been performed. This behavior is described in this PHP library documentation page — see the "Behavior" section.
It's important to know that even though the client was successfully instantiated, it does not mean your user/password pair is valid , and it doesn't automatically grant you access to anything . Your code has yet to try accessing any information, so your authentication has not been verified.
When you first create a MongoDB Atlas cluster, there's a "Connect" button in the GUI to retrieve the instance's URL. If no user database exists, you will be prompted to add one, and add an IP address to the access list.
In the MongoDB Atlas GUI sidebar, there's a "Security" section with links to the "Database Access" and "Network Access" configuration pages. "Database Access" is where you create database users and their privileges. "Network Access" lets you add IP addresses to the IP access list.
Next, you can do a first operation that requires an I/O connection and an authentication, such as listing the databases with
listDatabaseNames()
, as shown in the code block below. If it succeeds, your user/password pair is valid. If it fails, it could be that the pair is invalid or the user does not have the proper privileges.1 try { 2 // if listDatabaseNames() works, your authorization is valid 3 $databases_list_iterator = $client->listDatabaseNames(); // asks for a list of database names on the cluster 4 5 $databases_list = iterator_to_array( $databases_list_iterator ); 6 echo( MSG_CLIENT_AUTH_SUCCESS ); 7 } 8 catch (\Exception $e) { 9 // Fail if incorrect user/password, or not authorized 10 // Could be another issue, check content of $e->getMessage() 11 echo( MSG_EXCEPTION. $e->getMessage() ); 12 exit(); 13 }
There are other reasons why any MongoDB command could fail (connectivity loss, etc.), and the exception message will reveal that. These first initialization steps are common points of friction as cluster URLs vary from project to project, IPs change, and passwords are reset.
If you haven't performed CRUD operation with MongoDB before, we have a great tutorial entitled "Creating, Reading, Updating, and Deleting MongoDB Documents with PHP." Here, we'll look at the error handling mechanisms.
We will access one of the sample databases called "sample_analytics ," and read/write into the "customers" collection. If you're unfamiliar with MongoDB's terminology, here's a quick overview of the MongoDB database and collections.
Sometimes, ensuring the connected cluster contains the expected database(s) and collection(s) might be a good idea. In our code sample, we can check as follows:
1 // check if our desired database is present in the cluster by looking up its name 2 $workingdbname = 'sample_analytics'; 3 if ( in_array( $workingdbname, $databases_list ) ) { 4 echo( MSG_DATABASE_FOUND." '$workingdbname'<br>" ); 5 } 6 else { 7 echo( MSG_DATABASE_NOT_FOUND." '$workingdbname'<br>" ); 8 exit(); 9 } 10 11 // check if your desired collection is present in the database 12 $workingCollectionname = 'customers'; 13 $collections_list_itrerator = $client->$workingdbname->listCollections(); 14 $foundCollection = false; 15 16 $collections_list_itrerator->rewind(); 17 while( $collections_list_itrerator->valid() ) { 18 if ( $collections_list_itrerator->current()->getName() == $workingCollectionname ) { 19 $foundCollection = true; 20 echo( MSG_COLLECTION_FOUND." '$workingCollectionname'<br>" ); 21 break; 22 } 23 $collections_list_itrerator->next(); 24 } 25 26 if ( !$foundCollection ) { 27 echo( MSG_COLLECTION_NOT_FOUND." '$workingCollectionname'<br>" ); 28 exit(); 29 }
MongoDB CRUD operations have a multitude of legitimate reasons to encounter an exception. The general way of handling these errors is to put your operation in a try/catch block to avoid a fatal error.
If no exception is encountered, most operations return a document containing information about how the operation went.
For example, write operations return a document that contains a write concern "isAcknowledged" boolean and a WriteResult object. It has important feedback data, such as the number of matched and modified documents (among other things). Your app can check to ensure the operation performed as expected.
If an exception does happen, you can add further checks to see exactly what type of exception. For reference, look at the MongoDB exception class tree and keep in mind that you can get more information from the exception than just the message. The driver's ServerException class can also provide the exception error code, the source code line and the trace, and more!
For example, a common exception occurs when the application tries to insert a new document with an existing unique ID. This could happen for many reasons, including in high concurrency situations where multiple threads or clients might attempt to create identical records.
MongoDB maintains an array of tests for its PHP Library (see DocumentationExamplesTest.php on Github). It contains great code examples of various queries, with error handling. I highly recommend looking at it and using it as a reference since it will stay up to date with the latest driver and APIs.
This article was intended to introduce MongoDB error handling in PHP by highlighting common pitfalls and frequently asked questions we answer. Understanding the various MongoDB error-handling mechanisms will make your application rock-solid, simplify your development workflow, and ultimately make you and your team more productive.
To learn more about using MongoDB in PHP, learn from our PHP Library tutorial, and I invite you to connect via the PHP section of our developer community forums.
- MongoDB PHP Driver Documentation provides thorough documentation describing how to use PHP with your MongoDB cluster.
- MongoDB Query Document documentation details the full power available for querying MongoDB collections.