Beginning cloud development with cloudControl – Part 3 – MongoDB

Here we are at part three of the beginning cloud development with cloudControl series and in this part, we're adding mongoDB support. In part one of the series, we laid the foundation for the application and got up to speed with what cloudControl is, why it works and how to get started using it.

Then in part two, we started to flesh out the application that we started building in part one and added MySQL support to it. We showed how to work with cloudControl to manage the key requirements, such as enabling MySQL support, connecting to the MySQL database and keeping the database up to date from a maintenance perspective (creating the database schema and loading data in to the database).

In this, the third part of the series, we're replacing MySQL that we introduced in part two with mongoDB support. If you're not familiar with mongoDB, then I strongly encourage you to have a read of the

Getting Started with MongoDB article that I wrote for nettuts+ a little while back. It will show you how to get started, installing and learning the basics of this great NoSQL technology.

To make this process as simple as possible, we're going to be using the superb Shanty Mongo library - designed for use with Zend Framework, but it works equally well standalone. As the net result is not a lot different from where we ended up at the end of part two of the series, this will be a pretty succinct and concise post. So without any further ado, let's get started

Step 1 - Download Shanty-Mongo Zend Framework library for mongoDB

Ok, grab a copy of the shanty-Mongo library from the github repo, alternatively, clone a copy of the repo. When you have a copy ready, place the Shanty directory, in the library directory of the project in to the library directory of our project.

After this, we need to register the namespace for it with our existing Zend Autoloader. Normally this would be done in the application.ini config file, but as we're not using the MVC approach to Zend, then we need to do this manually. So at the top of the config.php file, register the namespace. You file should similar to the output below:

[php] require_once(&'Zend/Loader/Autoloader.php'); $autoloader = Zend_Loader_Autoloader::getInstance(); $autoloader->registerNamespace(&'Shanty_'); // database configuration $config = new Zend_Config_Ini( APPLICATION_PATH . &'/config/application.ini', APPLICATION_ENV ); [/php]

With that, we're ready to start using the library.

Step 2 - Enable mongoDB support in the project

From your terminal, change to the project directory. In there, we need to enable mongoDB support. To make this simpler, I've created a new branch, mongodb, so please don't get confused by the output below in the screenshots. To enable mongoDB support, we add the cloudControl add-on as follows:

[bash] cctrlapp maltbluedev/mongodb addon.add [/bash]

Nothing hard about this, right? But as well as enabling the add on, we need the configuration options so that we can configure our application appropriately. To do that, run the command below:

[bash] cctrlapp maltbluedev/mongodb addon [/bash]

That will give us output similar to that below:

Add mongodb support to cloudControl project

You can see that it's listed the settings for:

  • password
  • hostname
  • username
  • database
  • dbsize

Step 3 – Update the Configuration file

In the configuration file, application.ini, we now need to add support for mongoDB, just like we added support for MySQL previously. So, in your favourite text editor, open it up and add the following configuration settings:

[bash] [mongodb: production] mongodb.password = pEvtfVTdRgSs9JQ = mongodb.username = depd2nkk5wk mongodb.database = depd2nkk5wk [/bash]

You can see that we've created an environment that matches the branch we're on, mongodb and added the settings that we retrieved from the add on previously. With that, we're ready to start converting our code over to mongoDB, from MySQL.

Step 4 - Convert the classes over to mongoDB


In a lot of instances where I've used the Shanty-Mongo library, there's not been authentication in place, however as we've seen and as is appropriate, the configuration of mongoDB supplied by cloudControl requires authentication to continue. So near the top of our config.php file, where we registered the Shanty namespace, we need to add a secured connection to our mongoDB database.

To do that, we need simply call the static addConnections class, passing in our configuration object. Have a look at the code below which does just this:

[php] Shanty_Mongo::addConnections($config->mongodb); [/php]

When this is done, all connections from here on in will attempt to use the credentials we've specified.

The Model Class

Shanty-Mongo manages interaction with mongoDB in a rather ORM fashion. For every database, we have a class. In that class, we specify the document and collection information. For a solid introduction to using Shanty-Mongo, I encourage you to read the excellent markdown readme that comes with the library. This will give you all you need to get up to speed with the library very quickly.

Gladly, our model needs are very simple. Have a look at the class below which takes care of everything for us:

[php] class Staff extends Shanty_Mongo_Document { protected static $_db = &'depd2nkk5wk'; protected static $_collection = &'StaffList';

protected static $_requirements = array( &'firstName' => &'Required', &'lastName', 'emailAddress' => array(&'Required', &'Validator:EmailAddress'), &'occupation', ); } [/php]

You can see that we've named it after the database, Staff. We've specified the database from the information we retrieved from the add on configuration. We've specified a simple collection name of StaffList and then setup the document requirements, which closely match the database table schema we were previously using.

You can see that we've specified that the firstName and emailAddress fields are required, but that the lastName and occupation fields aren't. We've also specified that the emailAddress fields also needs to validate against the EmailAddress validator. This seems only right so that junk information is not entered and we can maintain a sense of proper data integrity.

As a quick note, we didn't need to specifically mention the lastName and occupation field here. But for the sake of complete transparency, it seemed appropriate. MongoDB won't mind and will add the fields as needed.

The Add Form

Nothing changes with the generation of the form, so we can leave that alone. What does change is the process of saving the information after a successful validation. So remove the old code that references the database and replace it with the following:

[php] $staffMember = new Staff(); $staffMember->firstName = $form->getValue(&'firstName'); $staffMember->lastName = $form->getValue(&'lastName'); $staffMember->emailAddress = $form->getValue('emailAddress'); $staffMember->occupation = $form->getValue(&'occupation'); $status = $staffMember->save(); [/php]

What we've done is to create a new Staff object and set the properties of it with the information supplied in the successfully validated form. After that, we just call the save method and the information is persisted to the database. Simplicity is bliss.

The Edit Form

As with the add form, nothing changes with the generation of the form, so leave that be. However, we change the code that runs after a successful validation and the code that retrieves the information about the staff member when the page is loaded.

So remove the old $form->setDefaults code and replace it with the code below:

[php] $staffMember = Staff::find($_GET[&'id']); $form = getManageForm(); $form->setDefaults(array( &'firstName' => $staffMember->firstName, &'lastName' => $staffMember->lastName, 'emailAddress' => $staffMember->emailAddress, &'occupation' => $staffMember->occupation, &'id' => $_GET[&'id'] )) ->setAction(&'/edit.php?id='.$_GET[&'id']); [/php]

This attempts to instantiate an object based on the id value retrieved from the GET super global array. This id value won't be a simple integer as with MySQL auto-increment values. Instead it will be a MongoID value. You can read more about those in the PHP mongoDB documentation.

Ok, now we need to replace the code that updates the information in our mongodb database after a successful form validation. Replace the database code from part two with the code below:

[php] $staffMember = Staff::find($_GET[&'id']); $staffMember->firstName = $form->getValue(&'firstName'); $staffMember->lastName = $form->getValue(&'lastName'); $staffMember->emailAddress = $form->getValue('emailAddress'); $staffMember->occupation = $form->getValue(&'occupation'); $status = $staffMember->save(); [/php]

This code will attempt to instantiate an object, based on the id value and then update the properties of it and call the save method to persist the information. How simple can it be.

The Delete Form

The delete form only requires a minor change. As with the add and edit forms, replace the code after successful form validation with the code below:

[php] $staffMember = Staff::find($_GET[&'id']); $staffMember->delete(); [/php]

As with the edit form, this instantiates an document with the id value from the GET super global then calls the delete method on it to remove the document from the database.

The List Form

At the top of the form, call the following method, which will retrieve a collection of all the documents in the staff database:

[php] $staffList = Staff::all(); [/php]

After that we can iterate over the collection as we did previously and display the members in our staff database.

Step 5 - Disable MySQL support

Ok, we're almost done, just a bit more to go. Now, as we no longer need MySQL support, we need to remove it. So run the following command:

[bash] cctrlapp maltbluedev/mongodb addon.remove [/bash]

Step 6 - Deploying the Changes

As with all code, we need to deploy the changes. So commit the changes to the branch and then run the push and deploy changes with the cctrlapp command line utility:

[bash] cctrlapp maltbluedev/mongodb push cctrlapp maltbluedev/mongodb deploy [/bash]

After about a minute, all the changes will be deployed and ready to go. When that's done, we can now view our updated application at:

Winding Up

So, you can see just how easy it is to integrate mongodb into your application with cloudControl. It's even easier than with MySQL. We simply need to enable the addon, migrate our code and deploy our changes to the project. Perfectly simple and practical, requiring next to no knowledge of mongoDB to get up and running quickly. It's yet another win for cloudControl.

About Matthew

Matthew Setter Matthew Setter is a PHP & Zend Framework specialist. If you're in need of a custom software application, need to migrate an existing legacy application, or want to know your current application's GPA - get in touch.