Getting Started with MongoLab: Part 2
In the first article about MongoLab, I showed you how to get set up with MongoDB for local development, and MongoLab, the PaaS service built specifically to handle remote deployments of a MongoDB database.
In this article I am going to show you how to work seamlessly with MongoLab to continue building a simple PHP app that uses a MongoDB database hosted on MongoLab.
I am also going to show you a better way to connect to MongoLab from your own computer. It eliminates the need for a local instance of MongoDB to be running at all.
Improved connection to MongoDB
There seems to be an issue with MongDB where the default connection parameters are set for localhost. That means, as shown in the first article, it has to be running and then a connection made to MongoLab via the shell.
Changing the installation process on your own machine for MongoDB solves the problem. On my Mac, I used the popular package manager called HomeBrew to install MongoDB.
Once you have HomeBrew installed, it is simply a matter of running:
brew install mongodb
from the terminal app. Make sure you note what appears after the installation completes – there is some very helpful information provided. I’ll include it here for reference:
==> Caveats
If this is your first install, automatically load on login with:
mkdir -p ~/Library/LaunchAgents
cp /usr/local/Cellar/mongodb/2.0.3-x86_64/homebrew.mxcl.mongodb.plist ~/Library/LaunchAgents/
launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.mongodb.plist
If this is an upgrade and you already have the homebrew.mxcl.mongodb.plist loaded:
launchctl unload -w ~/Library/LaunchAgents/homebrew.mxcl.mongodb.plist
cp /usr/local/Cellar/mongodb/2.0.3-x86_64/homebrew.mxcl.mongodb.plist ~/Library/LaunchAgents/
launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.mongodb.plist
Or start it manually:
mongod run --config /usr/local/Cellar/mongodb/2.0.3-x86_64/mongod.conf
The launchctl plist above expects the config file to be at /usr/local/etc/mongod.conf.
If this is a first install, you can copy one from /usr/local/Cellar/mongodb/2.0.3-x86_64/mongod.conf:
cp /usr/local/Cellar/mongodb/2.0.3-x86_64/mongod.conf /usr/local/etc/mongod.conf
==> Summary
What about Windows users?
The recommended way to install MongoDB for Windows is via the pre-built binaries. That will provide the same capability described in this article.
I’m on Linux, what do I do?
There is specific advice for the popular Linux distros on the MongoDB web site.
Connecting to MongoLab
I’m going to assume that you have an account set up as described in part 1. If you have, then you can jump into the console/terminal window and enter this command (found in the database window on your MongoLab account):
mongo youraccount.mongolab.com:31347/your_database -u <user> -p <password>
You will be connected directly to the database you have hosted on the cloud at MongoLab. back in the console/terminal type:
show collections
This will present a list of the collections you currently have in your database. Remember that a collection is roughly equivalent to a database table in MongoDB speak.
So now we have a direct connection for our MongoLab database, so we will continue building our little app.
Adding Tasks
So if you are following along from the last article, you will have a basic list of tasks displayed in your browser. The tasks are being read from our MongoLab database, but we can work with the data just as if we were using localhost.
We can add documents through the MongoLab web interface:
Or you could install one of the GUI tools available for MongoDB:
- MongoHub – Mac
- MongoVue – Windows
- JMongoBrowser – Windows, Mac, Linux
That is another nice feature of MongoLab. Being able to connect to the cloud service means that you can do the same from the GUI’s listed above:
Time for code
We left off last time with a list of tasks being displayed. It would be nice if we could add a task via PHP though, using a simple web form. Create a new file in the project called ‘create.php’ and then add a simple form to it:
<!DOCTYPE html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Add a task</title>
<link type="text/css" rel="stylesheet" href="" />
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<h1>Task Creator</h1>
<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
<h3>Title</h3>
<p><input type="text" name="title" id="title" /></p>
<h3>Status</h3>
<p><input type="text" name="status" id="status" /></p>
<h3>Context</h3>
<p><input type="text" name="context" id="context" /></p>
<p><input type="submit" name="submit" value="Save"/></p>
</form>
</body>
</html>
Notice that we are using PHP_SELF to post the form back to itself. That way, we can do a simple conditional test to see what state the form is in.
Connect to MongoLab
Next, we can write our connection routine at the top of the file to connect to MongoLab:
<?php
try
{
$connection = new Mongo('mongodb://<user>:<password>your_database.mongolab.com:31347/your_database');
$database = $connection->selectDB('your_database');
$collection = $database->selectCollection('tasks');
}
catch(MongoConnectionException $e)
{
die("Failed to connect to database ".$e->getMessage());
}
Insert document routine
Now we can add an array of variables passed in from the form as $_POST values in the try block:
try {
$connection = new Mongo('mongodb://<user>:<password>your_database.mongolab.com:31347/your_database');
$database = $connection->selectDB('your_database');
$collection = $database->selectCollection('tasks');
$task = array();
$task['title'] = $_POST['title'];
$task['status'] = $_POST['status'];
$task['context'] = $_POST['context'];
$task['saved_at'] = new MongoDate();
$collection->insert($task);
There is nothing unusual going on here apart from the call to $collection->insert. That is a call to a method in the PHP Mongo class; it attempts an insert into the collection we have referenced in our connection.
We can add another “catch” exception here too, in case the insert doesn’t work:
catch(MongoException $e)
{
$die('Failed to insert data '.$e->getMessage());
}
Wire up the form
Now all we need is to put a trigger in to check: that the form needs to be shown, or a successful insert message, depending on whether a record has been added.
Right at the top of the PHP block create an empty variable called $trigger. Then add a conditional test to see if the form submit button variable is set and has a value. If it has, then we can trigger the save action, otherwise we just need to display the form:
$trigger = "";
if((!empty($_POST['submit'])) && ($_POST['submit'] === 'Save'))
{
$trigger = "do_save";
}
else
{
$trigger = "show_form";
}
Then we can add a further conditional test to see what value $trigger has and proceed accordingly. The whole PHP block now looks like this:
<?php
$trigger = "";
if((!empty($_POST['submit'])) && ($_POST['submit'] === 'Save'))
{
$trigger = "do_save";
}
else
{
$trigger = "show_form";
}
switch($trigger)
{
case 'do_save':
try
{
$connection = new Mongo('mongodb://<user>:<password>your_database.mongolab.com:31347/your_database');
$database = $connection->selectDB('andyhawthorne');
$collection = $database->selectCollection('tasks');
$task = array();
$task['title'] = $_POST['title'];
$task['status'] = $_POST['status'];
$task['context'] = $_POST['context'];
$task['saved_date'] = new MongoDate();
$collection->insert($task);
}
catch(MongoConnectionException $e)
{
die("Failed to connect to database ".$e->getMessage());
}
catch(MongoException $e)
{
$die('Failed to insert data '.$e->getMessage());
}
break;
case 'show_form':
default:
}
?>
You’ll notice that we have added an insert field: $task[‘saved_date’] = new MongoDate(). MongoDB will not complain, even though we haven’t used that field before. MongoDate() is a built-in timestamp function in the PHP driver.
The only thing left to do is:
<?php if ($trigger === 'show_form'): ?>
Add this above the opening form tag. Then after the closing form tag:
<?php else: ?>
<p>
Task saved. _id: <?php echo $task['_id'];?>.
<a href="<?php echo $_SERVER['PHP_SELF'];?>">Add another task?</a>
</p>
<?php endif;?>
This will respond to the conditional test at the top of our PHP block.
Try it out
Add some records with your snazzy new form. Here comes the great bit though. As you save each document it will be sent to your MongoLab database:
Updating and Deleting Records
MongoLab does not yet support bulk uploading from the web admin area, but you can create, edit, and delete documents. Just before we consider how to do that from PHP, lets look at the CRUD operations from within MongoLab itself.
When you click through to view a particular collection, you will see the documents displayed in a paginated list:
Clicking the “x” will indeed delete the document. Clicking on an individual document will send you through to the edit screen:
Edit away, and then save the new version. Easy eh?
What about from PHP?
For editing documents, the process is similar to inserting:
- Create a web form
- Connect to MongoLab and retrieve a document
- Populate the form with the correct record
- Save the changes
So far we have seen how to use the $collection->find() method that creates a result-set of all the documents in the collection. For selecting an individual document we can use something like this:
$id = $_REQUEST['id'];
$task = $collection->findOne(array('_id' => new MongoId($id)));
To run an update you can then build an array of form data the same as for an insert, and use code like this to run the update:
$id = $_REQUEST['id'];
$collection->update(array('_id' => new MongoId($id)), $form_data);
Where $form_data is the array of data sent in from your web form. Deleting a document follows the same idea:
$id = $_REQUEST['id'];
$collection->remove(array('_id' => new MongoId($id)));
Finally…
Working with MongoDB has been made much easier thanks to MongoLab. The fact that it runs your database in the cloud, means that you can develop your application, and deploy it, without having to worry about the database stuff at all.
In this article you have seen a fully worked example of inserting documents via PHP, and you have also seen how to manage those documents in the MongoLab web admin area. Once the ability to do bulk inserts from the admin area is added, MongoLab will have everything you need for deploying MongoDB databases. The features it already has, makes the whole process of building a MongoDB based PHP web app simple.
Leaf image via Shutterstock