Creating, Reading, Updating, and Deleting MongoDB Documents With PHP
Rate this quickstart
Welcome to Part 2 of this quick start guide for MongoDB and PHP. In the previous article, I walked through the process of installing, configuring, and setting up PHP, Apache, and the MongoDB Driver and Extension so that you can effectively begin building an application leveraging the PHP, MongoDB stack.
I highly recommend visiting the first article in this series to get set up properly if you have not previously installed PHP and Apache.
I've created each section with code samples. And I'm sure I'm much like you in that I love it when a tutorial includes examples that are standalone... They can be copy/pasted and tested out quickly. Therefore, I tried to make sure that each example is created in a ready-to-run fashion.
These samples are available in this repository, and each code sample is a standalone program that you can run by itself. In order to run the samples, you will need to have installed PHP, version 8, and you will need to be able to install additional PHP libraries using
Compose
. These steps are all covered in the first article in this series.Additionally, while I cover it in this article, it bears mentioning upfront that you will need to create and use a
.env
file with your credentials and the server name from your MongoDB Atlas cluster.This guide is organized into a few sections over a few articles. This first article addresses the installation and configuration of your development environment. PHP is an integrated web development language. There are several components you typically use in conjunction with the PHP programming language.
Video Introduction and Overview
Let's start with an overview of what we'll cover in this article.
To connect to a MongoDB Atlas cluster, use the Atlas connection string for your cluster:
1 2 3 $client = new MongoDB\Client( 4 'mongodb+srv://<username>:<password>@<cluster-address>/test?w=majority' 5 ); 6 $db = $client->test;
Just a note about language. Throughout this article, we use the term
create
and insert
interchangeably. These two terms are synonymous. Historically, the act of adding data to a database was referred to as CREATING
. Hence, the acronym CRUD
stands for Create, Read, Update, and Delete. Just know that when we use create or insert, we mean the same thing.When we connect to MongoDB, we need to specify our credentials as part of the connection string. You can hard-code these values into your programs, but when you commit your code to a source code repository, you're exposing your credentials to whomever you give access to that repository. If you're working on open source, that means the world has access to your credentials. This is not a good idea. Therefore, in order to protect your credentials, we store them in a file that does not get checked into your source code repository. Common practice dictates that we store this information only in the environment. A common method of providing these values to your program's running environment is to put credentials and other sensitive data into a
.env
file.1 MDB_USER="yourusername" 2 MDB_PASS="yourpassword" 3 ATLAS_CLUSTER_SRV="mycluster.zbcul.mongodb.net"
To create your own environment file, create a file called
.env
in the root of your program directory. You can simply copy the example environment file I've provided and rename it to .env
. Be sure to replace the values in the file yourusername
, yourpassword
, and mycluster.zbcul.mongodb.net
with your own.Once the environment file is in place, you can use
Composer
to install the DotEnv library, which will enable us to read these variables into our program's environment. See the first article in this series for additional setup instructions.1 $ composer require vlucas/phpdotenv
Once installed, you can incorporate this library into your code to pull in the values from your
.env
file.1 $dotenv = Dotenv\Dotenv::createImmutable(__DIR__); 2 $dotenv->load();
Next, you will be able to reference the values from the
.env
file using the $_ENV[]
array like this:1 echo $_ENV['MDB_USER'];
See the code examples below to see this in action.
The MongoDBCollection::insertOne() method inserts a single document into MongoDB and returns an instance of MongoDBInsertOneResult, which you can use to access the ID of the inserted document.
1 2 3 require_once __DIR__ . '/vendor/autoload.php'; 4 $dotenv = Dotenv\Dotenv::createImmutable(__DIR__); 5 $dotenv->load(); 6 7 $client = new MongoDB\Client( 8 'mongodb+srv://'.$_ENV['MDB_USER'].':'.$_ENV['MDB_PASS'].'@'.$_ENV['ATLAS_CLUSTER_SRV'].'/test' 9 ); 10 11 $collection = $client->test->users; 12 13 $insertOneResult = $collection->insertOne([ 14 'username' => 'admin', 15 'email' => 'admin@example.com', 16 'name' => 'Admin User', 17 ]); 18 19 printf("Inserted %d document(s)\n", $insertOneResult->getInsertedCount()); 20 21 var_dump($insertOneResult->getInsertedId());
You should see something similar to:
1 Inserted 1 document(s) 2 object(MongoDB\BSON\ObjectId)#11 (1) { 3 ["oid"]=> 4 string(24) "579a25921f417dd1e5518141" 5 }
The output includes the ID of the inserted document.
The MongoDBCollection::insertMany() method allows you to insert multiple documents in one write operation and returns an instance of MongoDBInsertManyResult, which you can use to access the IDs of the inserted documents.
1 2 3 require_once __DIR__ . '/vendor/autoload.php'; 4 $dotenv = Dotenv\Dotenv::createImmutable(__DIR__); 5 $dotenv->load(); 6 7 $client = new MongoDB\Client( 8 'mongodb+srv://'.$_ENV['MDB_USER'].':'.$_ENV['MDB_PASS'].'@'.$_ENV['ATLAS_CLUSTER_SRV'].'/test' 9 ); 10 11 $collection = $client->test->users; 12 13 $insertManyResult = $collection->insertMany([ 14 [ 15 'username' => 'admin', 16 'email' => 'admin@example.com', 17 'name' => 'Admin User', 18 ], 19 [ 20 'username' => 'test', 21 'email' => 'test@example.com', 22 'name' => 'Test User', 23 ], 24 ]); 25 26 printf("Inserted %d document(s)\n", $insertManyResult->getInsertedCount()); 27 28 var_dump($insertManyResult->getInsertedIds());
You should see something similar to the following:
1 Inserted 2 document(s) 2 array(2) { 3 [0]=> 4 object(MongoDB\BSON\ObjectId)#18 (1) { 5 ["oid"]=> 6 string(24) "6037b861301e1d502750e712" 7 } 8 [1]=> 9 object(MongoDB\BSON\ObjectId)#21 (1) { 10 ["oid"]=> 11 string(24) "6037b861301e1d502750e713" 12 } 13 }
Reading documents from a MongoDB database can be accomplished in several ways, but the most simple way is to use the
$collection->find()
command.1 function find($filter = [], array $options = []): MongoDB\Driver\Cursor
The following sample code specifies search criteria for the documents we'd like to find in the
restaurants
collection of the sample_restaurants
database. To use this example, please see the Available Sample Datasets for Atlas Clusters.1 2 3 // 4 // This example uses data from the Sample Datasets in MongoDB Atlas 5 // To load, and use this sample data, see https://docs.atlas.mongodb.com/sample-data/available-sample-datasets/ 6 // 7 8 require_once __DIR__ . '/vendor/autoload.php'; 9 $dotenv = Dotenv\Dotenv::createImmutable(__DIR__); 10 $dotenv->load(); 11 12 $client = new MongoDB\Client( 13 'mongodb+srv://'.$_ENV['MDB_USER'].':'.$_ENV['MDB_PASS'].'@'.$_ENV['ATLAS_CLUSTER_SRV'].'/sample_restaurants' 14 ); 15 16 $collection = $client->sample_restaurants->restaurants; 17 18 $cursor = $collection->find( 19 [ 20 'cuisine' => 'Italian', 21 'borough' => 'Manhattan', 22 ], 23 [ 24 'limit' => 5, 25 'projection' => [ 26 'name' => 1, 27 'borough' => 1, 28 'cuisine' => 1, 29 ], 30 ] 31 ); 32 33 foreach ($cursor as $restaurant) { 34 var_dump($restaurant); 35 };
You should see something similar to the following output:
1 object(MongoDB\Model\BSONDocument)#20 (1) { 2 ["storage":"ArrayObject":private]=> 3 array(4) { 4 ["_id"]=> 5 object(MongoDB\BSON\ObjectId)#26 (1) { 6 ["oid"]=> 7 string(24) "5eb3d668b31de5d588f42965" 8 } 9 ["borough"]=> 10 string(9) "Manhattan" 11 ["cuisine"]=> 12 string(7) "Italian" 13 ["name"]=> 14 string(23) "Isle Of Capri Resturant" 15 } 16 } 17 object(MongoDB\Model\BSONDocument)#19 (1) { 18 ["storage":"ArrayObject":private]=> 19 array(4) { 20 ["_id"]=> 21 object(MongoDB\BSON\ObjectId)#24 (1) { 22 ["oid"]=> 23 string(24) "5eb3d668b31de5d588f42974" 24 } 25 ["borough"]=> 26 string(9) "Manhattan" 27 ["cuisine"]=> 28 string(7) "Italian" 29 ["name"]=> 30 string(18) "Marchis Restaurant" 31 } 32 } 33 object(MongoDB\Model\BSONDocument)#26 (1) { 34 ["storage":"ArrayObject":private]=> 35 array(4) { 36 ["_id"]=> 37 object(MongoDB\BSON\ObjectId)#20 (1) { 38 ["oid"]=> 39 string(24) "5eb3d668b31de5d588f42988" 40 } 41 ["borough"]=> 42 string(9) "Manhattan" 43 ["cuisine"]=> 44 string(7) "Italian" 45 ["name"]=> 46 string(19) "Forlinis Restaurant" 47 } 48 } 49 object(MongoDB\Model\BSONDocument)#24 (1) { 50 ["storage":"ArrayObject":private]=> 51 array(4) { 52 ["_id"]=> 53 object(MongoDB\BSON\ObjectId)#19 (1) { 54 ["oid"]=> 55 string(24) "5eb3d668b31de5d588f4298c" 56 } 57 ["borough"]=> 58 string(9) "Manhattan" 59 ["cuisine"]=> 60 string(7) "Italian" 61 ["name"]=> 62 string(22) "Angelo Of Mulberry St." 63 } 64 } 65 object(MongoDB\Model\BSONDocument)#20 (1) { 66 ["storage":"ArrayObject":private]=> 67 array(4) { 68 ["_id"]=> 69 object(MongoDB\BSON\ObjectId)#26 (1) { 70 ["oid"]=> 71 string(24) "5eb3d668b31de5d588f42995" 72 } 73 ["borough"]=> 74 string(9) "Manhattan" 75 ["cuisine"]=> 76 string(7) "Italian" 77 ["name"]=> 78 string(8) "Arturo'S" 79 } 80 }
Updating documents involves using what we learned in the previous section for finding and passing the parameters needed to specify the changes we'd like to be reflected in the documents that match the specific criterion.
There are two specific commands in the PHP Driver vocabulary that will enable us to
update
documents.MongoDB\Collection::updateOne
- Update, at most, one document that matches the filter criteria. If multiple documents match the filter criteria, only the first matching document will be updated.MongoDB\Collection::updateMany
- Update all documents that match the filter criteria.
These two work very similarly, with the obvious exception around the number of documents impacted.
Let's start with
MongoDB\Collection::updateOne
. The following code sample finds a single document based on a set of criteria we pass in a document and $set
's values in that single document.1 2 3 require_once __DIR__ . '/vendor/autoload.php'; 4 $dotenv = Dotenv\Dotenv::createImmutable(__DIR__); 5 $dotenv->load(); 6 7 $client = new MongoDB\Client( 8 'mongodb+srv://'.$_ENV['MDB_USER'].':'.$_ENV['MDB_PASS'].'@'.$_ENV['ATLAS_CLUSTER_SRV'].'/sample_restaurants' 9 ); 10 11 $collection = $client->sample_restaurants->restaurants; 12 13 $updateResult = $collection->updateOne( 14 [ 'restaurant_id' => '40356151' ], 15 [ '$set' => [ 'name' => 'Brunos on Astoria' ]] 16 ); 17 18 printf("Matched %d document(s)\n", $updateResult->getMatchedCount()); 19 printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
You should see something similar to the following output:
1 Matched 1 document(s) 2 Modified 1 document(s)
Now, let's explore updating multiple documents in a single command execution.
The following code sample updates all of the documents with the borough of "Queens" by setting the active field to true:
1 2 3 require_once __DIR__ . '/vendor/autoload.php'; 4 $dotenv = Dotenv\Dotenv::createImmutable(__DIR__); 5 $dotenv->load(); 6 7 $client = new MongoDB\Client( 8 'mongodb+srv://'.$_ENV['MDB_USER'].':'.$_ENV['MDB_PASS'].'@'.$_ENV['ATLAS_CLUSTER_SRV'].'/sample_restaurants' 9 ); 10 11 $collection = $client->sample_restaurants->restaurants; 12 13 $updateResult = $collection->updateMany( 14 [ 'borough' => 'Queens' ], 15 [ '$set' => [ 'active' => 'True' ]] 16 ); 17 18 printf("Matched %d document(s)\n", $updateResult->getMatchedCount()); 19 printf("Modified %d document(s)\n", $updateResult->getModifiedCount());
You should see something similar to the following:
1 Matched 5656 document(s) 2 Modified 5656 document(s)
When updating data in your MongoDB database, it's important to consider
write concern
. Write concern describes the level of acknowledgment requested from MongoDB for write operations to a standalone mongod
, replica sets, or sharded clusters.To understand the current value of write concern, try the following example code:
1 $collection = (new MongoDB\Client)->selectCollection('test', 'users', [ 2 'writeConcern' => new MongoDB\Driver\WriteConcern(1, 0, true), 3 ]); 4 5 var_dump($collection->getWriteConcern());
See https://mongodb.prakticum-team.ru/proxy/docs.mongodb.com/manual/reference/write-concern/ for more information on write concern.
Just as with updating and finding documents, you have the ability to delete a single document or multiple documents from your database.
MongoDB\Collection::deleteOne
- Deletes, at most, one document that matches the filter criteria. If multiple documents match the filter criteria, only the first matching document will be deleted.MongoDB\Collection::deleteMany
- Deletes all documents that match the filter criteria.
Let's start with deleting a single document.
The following code sample deletes one document in the users collection that has "ny" as the value for the state field:
1 2 3 // 4 // This example uses data from the Sample Datasets in MongoDB Atlas 5 // To load, and use this sample data, see https://docs.atlas.mongodb.com/sample-data/available-sample-datasets/ 6 // 7 8 require_once __DIR__ . '/vendor/autoload.php'; 9 $dotenv = Dotenv\Dotenv::createImmutable(__DIR__); 10 $dotenv->load(); 11 12 $client = new MongoDB\Client( 13 'mongodb+srv://'.$_ENV['MDB_USER'].':'.$_ENV['MDB_PASS'].'@'.$_ENV['ATLAS_CLUSTER_SRV'].'/sample_restaurants' 14 ); 15 16 $collection = $client->sample_restaurants->restaurants; 17 18 $deleteResult = $collection->deleteOne(['cuisine' => 'Hamburgers']); 19 20 printf("Deleted %d document(s)\n", $deleteResult->getDeletedCount());
You should see something similar to the following output:
1 Deleted 1 document(s)
You will notice, if you examine the
sample_restaurants
database, that there are many documents matching the criteria { "cuisine": "Hamburgers" }
. However, only one document was deleted.Deleting multiple documents is possible using
MongoDB\Collection::deleteMany
. The following code sample shows how to use deleteMany
.1 2 3 // 4 // This example uses data from the Sample Datasets in MongoDB Atlas 5 // To load, and use this sample data, see https://docs.atlas.mongodb.com/sample-data/available-sample-datasets/ 6 // 7 8 require_once __DIR__ . '/vendor/autoload.php'; 9 $dotenv = Dotenv\Dotenv::createImmutable(__DIR__); 10 $dotenv->load(); 11 12 $client = new MongoDB\Client( 13 'mongodb+srv://'.$_ENV['MDB_USER'].':'.$_ENV['MDB_PASS'].'@'.$_ENV['ATLAS_CLUSTER_SRV'].'/sample_restaurants' 14 ); 15 16 $collection = $client->sample_restaurants->restaurants; 17 $deleteResult = $collection->deleteMany(['cuisine' => 'Hamburgers']); 18 19 printf("Deleted %d document(s)\n", $deleteResult->getDeletedCount());
You should see something similar to the following output:
Deleted 432 document(s)
If you run this multiple times, your output will obviously differ. This is because you may have removed or deleted documents from prior executions. If, for some reason, you want to restore your sample data, visit: https://docs.atlas.mongodb.com/sample-data/available-sample-datasets/ for instructions on how to do this.
The basics of any language are typically illuminated through the process of creating, reading, updating, and deleting data. In this article, we walked through the basics of CRUD with PHP and MongoDB. In the next article in the series, will put these principles into practice with a real-world application.
Creating or inserting documents is accomplished through the use of:
Reading or finding documents is accomplished using:
Updating documents is accomplished through the use of:
Deleting or removing documents is accomplished using:
Questions? Comments? We'd love to connect with you. Join the conversation on the MongoDB Community Forums.
- MongoDB PHP Driver Documentation provides thorough documentation describing how to use PHP with our MongoDB cluster.
- MongoDB Query Document documentation details the full power available for querying MongoDB collections.