Finally Some Code!
Last week we ran through a couple exercises to help get you familiar with the data structure of MongoDB. This week we’re going to start learning how to access MongoDB using PHP.
Simple Page Template
There are a few chores we need to get out of the way before we can start doing actual database work. Like creating a space on our server for out project. I just dropped a “treasurebag” directory right into my web server’s www folder.
Next, if you remember back to the document design you’ll see that every single page is supposed to have the same same title and navigation menu, so it makes sense to create a single file to hold all this common data.
We’re also going to need some simple style rules to make the application look a little better. We could place this in a separate CSS file, but since we only have a few dozen lines of style rules we might as well just include it in the same page as the header. And since this isn’t a design tutorial I’m not really going to say much about the styling. We give the page a parchment color background to fit the fantasy theme, add some black outlines to tables and center some text. Nothing complex or beautiful but it does make everything a little more readable.
Header
This should all go into a file named “header.php”.
<!DOCTYPE html> <html> <head> <title>Treasure Bag</title> <style> body{ background:#F1F1D4 } #header-wrapper{ width:800px; text-align:center; border: solid black 3px; } #header-wrapper table{ width:100%; } #header-wrapper td{ width:33%; text-align:center; padding: 20px; } #content-wrapper{ width: 800px; padding: 20px; } #content-wrapper table{ border-collapse:collapse; width:500px; margin-top:10px; } #content-wrapper td{ border: solid black 1px; padding: 5px; margin: collapse; } </style> </head> <body> <div id="header-wrapper"> <h1>Treasure Bag</h1> <table> <tr> <td><a href="index.php">Inventory</a></td> <td><a href="add.php">Add Treasure</a></td> <td><a href="search.php">Search</a></td> </tr> </table> </div> <div id="content-wrapper">
Footer
There really isn’t anything we need to display at the bottom of every page, but the header has a lot of HTML elements that never get closed. So we’ll create a very simple footer file that clears all that up so that we don’t have to worry about it.
Please put these three lines into a file named “footer.php”.
</div> </body> </html>
Using Our Template
Using our page template is very simple. You just insert the header, add your content and then use the footer to finish everything up.
<?php include('header.php'); //YOUR CONTENT HERE include('footer.php'); ?>
Preparing PHP For MongoDB
Now that that’s out of the way we can get back to thinking about databases. But before we can start using MongoDB in our PHP applications we have to install a few extra PHP features. Just like with installing MongoDB itself this process will be a little different for every system and it’s up to you to figure it out. You probably want to start with the official page on MongoDB PHP support.
Connecting to MongoDB With PHP
I’m going to assume at this point that you’ve successfully installed the MongoDB PHP drivers and are ready to finally start coding. You might want to create a “sample.php” file to help you test the next few lines of code. Or you can wait until the end of tutorial when we create the first real page of our Treasure Bag application.
The first step in pulling data out of the database is to connect to it. So any PHP script that plans on talking to MongoDB needs this somewhere near the top:
$connection = new Mongo();
The reason this is so simple is because PHP assumes that you’re running MongoDB on “localhost” and with the default port. So you only have to tell PHP where to find your database if you’re doing something more complex, like trying to connect to a remote database. In that case you’ll have to give PHP a little more information about where to look.
$connection = new Mongo(“mongodb://yourremoteurlhere.com”);
Reading An Entire Database
Now that we have a connection, what do we do with it? How about we dump the contents of the entire “treasure” collection onto our page? After last week’s tutorial there should be at least a few documents in there we can look at.
You might remember that we were able to dump data on the command line by first choosing which database we wanted to use, then choosing a collection and finally calling find:
use treasurebag db.treasure.find()
The PHP solution is very similar:
$db = $connection->treasurebag; $db->treasure->find();
Alternatively, you can choose the database and the collection both in the same line like this:
$connection->treasurebag->treasure->find();
That’s not so bad. We’re using arrows instead of dots but otherwise everything looks the same. But wait! There’s one big difference. Using find in MongoDB just immediately dumped all of our treasure documents onto our screen. But in PHP find will give us a cursor, a special object that will give us documents one at a time. To dump everything on the screen we will have to take that cursor and keep asking for more documents by using getNext():
$cursor = $connection->treasurebag->treasure->find() while($document = $cursor->getNext()){ print_r($document); }
If you’ve been following along then visiting your “sample.php” page should show you a big lump of text with whatever data is still in your “treasure” collection from the last tutorial. If you get an error or just aren’t seeing anything try these troubleshooting tips:
- Make sure there is data in the “treasure” collection of the “treasurebag” database by firing up the Mongo console tool like we talked about last week.
- Make sure that you remembered to connect to MongoDB before trying to create the cursor. $connection = new Mongo() needs be the first thing in your script!
- Double check your spelling for database and collection names. One tiny typo is all it takes to start looking through a blank database instead of the real “treasurebag” database.
Accessing Individual Pieces Of Data
Just dumping our documents onto the page isn’t very practical. What if we only want to see part of a document? Like the name of a treasure or its price? The answer is pretty easy and I bet most of you figured it out just by looking at the print_r output from the example above.
For those of you who didn’t, remember that a MongoDB document is made up of key value pairs. To get a specific piece of data you just ask for the key you want and get back the value stored with it:
$document['key'];
So if you want to print out the name of an item all you have to do is:
echo $document['Name'];
Or if you need to store a price for later:
$price = $document['Price'];
Creating the Treasure Bag View Page
That’s everything you need to know to create the main “index.php” page of our Treasure Bag application. We have the page template, the MongoDB connection and we know how to use the cursor. All that’s left is to put it together. I’ve included my complete solution right below but you might want to try creating your own “index.php” page first. If you look at the design document you’ll see that we want to put all the treasures into a table that shows their name, price and type. And don’t forget to use our header and footer files!
Anyways, here’s my “index.php” file, which I saved to the same directory as “header.php” and “footer.php”:
<?php include('header.php'); $connection = new Mongo(); $cursor = $connection->treasurebag->treasure->find(); echo '<h2>Inventory</h2>'; echo '<button>Sort By Name</button>'; echo '<button>Sort By Price</button>'; echo '<table><tr><td>Name</td><td>Price</td><td>Type</td></tr>'; while($document = $cursor->getNext()){ $name = $document['Name']; $price = $document['Price']; $type = $document['Type']; echo "<tr><td>$name</td> <td>$price</td> <td>$type</td> </tr>"; } echo '</table>'; include('footer.php'); ?>
Screenshot of Success!
Let’s walk through this screenshot really quick. Up at the top you can see the title and the navigation links from “header.php”. Underneath that we have the actual inventory table created using data from our MongoDB cursor. You’ll also notice that we added two buttons for sorting right above the table. Right now they don’t actually do anything, but our design document tells us that we need them for later so we might as well add them now.
And that’s it for this week! Try using the MongoDB console to add new items to the “treasure” collection and then refresh “index.php” to see them show up in all their glory. Then tune in next week as we make the sort buttons actually sort and add a page for viewing item details.
BONUS!
If you’ve been following along with the bonus activities you should have designed a character view page and have a character collection with some sample data. Create a “characterlist.php” file that connects to this collection and puts all your characters into a table or list. You will also probably want to edit “header.php” to include links to this page. You might have to alter some of the style rules to make the menu work well with four links instead of three, but I’m sure a bonus obsessed programmer like you can handle it.