Symfony2 Tutorial 6 Homework

Ok, let's get Symfony downloaded and setup. Head over to and click "Download Now". If the site looks a little different for you, that's because the Internet loves to change things after we record screencasts! But no worries, just find the download page - all the steps will be the same.

Downloading Composer

We're going to use a tool called Composer to get the project started. Composer is PHP's package manager. That's a way of saying that it downloads external libraries into our project. Oh yea, and it's also the most important PHP innovation in years.

To get it, go to - you guessed it - and click Download. Depending on whether you have installed, copy one of the two install lines.

Open up your terminal and start typing wildly:

Hmm, ok, that didn't work. So let's try pasting the command instead. If you have PHP 5.4 installed, run this anywhere: we'll use PHP's built-in web server. If you don't, get with it! PHP 5.3 is ancient. But anyways, make sure you have Apache setup and run the command at the server's document root:

This downloads an executable PHP file called . If Composer complains with any warnings or errors, follow its recommendations to make sure your system doesn't panic when we use it.

Downloading the Standard Distribution

Go back to the download page and copy the Composer command. Change the target directory to say starwarsevents and the last part to say . This is the version number and is a neat way of making sure we get the latest and greatest.

This tells Composer to download the package into the directory. That's all you need to know for now - we're going to explore Composer later.

Ok, so downloading everything is going to take a few minutes. Composer is busy with 2 things at once. First, it's downloading a little example project that uses the Symfony libraries. Even while Composer is doing its thing, we can open a new terminal and move into the new directory. It contains a relatively small number of files and directories:

Second, our project depends on a bunch of 3rd-party libraries and Composer is downloading these into the directory. If you run , you'll see that more and more things are popping up here.

When that finishes, our terminal will become self-aware and start asking us configuration questions. Just hit enter through all of these - we can tweak the config later.

Setup Checks and Web Server Config

Let's make sure that our computer is ready to run Symfony. The project has a little PHP file - - that checks our computer and tells us if we're super-heroes on system setup or if our machine is missing some libraries.

We need to navigate to this script in our browser. So if you have PHP 5.4 or higher, just use the built-in PHP web server. Run this command from the root of our project:

If you get an error or are using Apache, we have a note on this chapter's page about all that.


This is just a shortcut for:

We now have a web server running at , which uses the directory as its doc root. We can just surf directly to the file:


If you're using Apache instead and downloaded the project to your Apache document root, then you can go to "localhost" and find your way to the script:

We'll talk more about a proper web server setup later.

If you see any scary "Major Problems", you'll need to fix those. But feel free to ignore any "Minor Problems" for now.

Permissions Craziness

You may see two major issues - permissions problems with the and directories. Ok, since this can be really annoying, we gotta get it fixed.

Basically, we need the cache and logs directories to be writable by our terminal user and our web server's user, like . And if a cache file is created by one user, that file needs to be modifiable by the other user. It's an epic battle of 2 UNIX users needing to mess with the same set of files.


If you're screaming , "If Symfony just creates cache files with 777 permissions, this wouldn't be an issue!", you're right! But that would be a security no-no for shared hosting #sadpanda

Of course, you're awesome and are using the PHP built-in web server. For us, our terminal user is our PHP web server user, so we don't have any issues.

If you're using Apache or are having issues, check out the sidebar on this page with some tips.


Fixing Permissions Issues

The easiest permissions fix is to add a little function to the top of 2 files. Pop open your project in your favorite editor, we love PhpStorm.

Open up and . You'll see a little line there - uncomment this:

What the heck? The function makes it so that cache and logs files are created as 777 (world writable).

Once you're done, set the permissions on the two cache and logs directories:

You shouldn't have any more issues, but if you do, just set the permissions again.

This method can be a security issue if you're deploying to a shared server. Check out Symfony's installation chapter for details on other ways to setup your permissions.

Loading up the First Page

Ok, we're ready to get to work. Check out our first real Symfony page, by hitting the file in your browser:


Hopefully a cute welcome page greets you. The project came with a few demo pages and you're looking at the first one. The code for these lives in the directory. You can see the rest of the demo pages by clicking the "Run The Demo" button.


If you're using Apache with the same setup as we've done, then the URL will be:

Directory Structure

Without writing any code, we already have a working project. Yea, I know, it's kinda lame and boring now, but it does have the normal directory structure.


Let's look at the dir. It holds configuration and a few other things that tie the whole project together. If your app were a computer, this would be the motherboard: it doesn't really do anything, but it controls everything.

Most of our code will live somewhere else, in directories called "bundles". These bundles are activated in the class and configured in the file inside .

For example, there's a core bundle called FrameworkBundle. It controls a lot of things, including the session timeout length. So if we needed to tweak this, we'd do it under the config key:

Routes are the URLs of your app, and they also live in this directory in the file. We'll master routes in a few minutes.

You can ignore everything else in the directory - we'll talk more about them when we cover environments.

The directory is also where the base layout file () and console script () live. More on those soon!


After , we have . You know what? Just forget you ever saw this directory. It has some executable files that Composer added, but nothing we'll ever need at this point.


Curious about the secrets behind Composer and this directory. Then do some homework!


All the magic and code-writing happens in the directory. We're going to fill it with sub-directories called "bundles". The idea is that each bundle has the code for a single feature or part of your app.

We're about 10 seconds away from nuking it, but if you want to enjoy the demo code, it lives here inside AcmeDemoBundle.


We already know about the directory - this is where Composer downloads outside libraries. It's kinda fat, with a ton of files in it. But no worries, you don't need to look in here, unless you want to dig around in some core files to see how things work. Actually, I love doing that! We'll tear open some core files later.


The last directory is . It's simple: this is your document root, so put your public stuff here, like CSS and JS files.

There are also two PHP files here that actually execute Symfony. One loads the app in the environment () and the other in the environment (). More on this environment stuff later.

Removing Demo Code

It's time to get serious, so let's get all of that demo code out of the way. First, take your wrecking ball to the directory:

Next, take out the reference to the bundle in your so Symfony doesn't look for it when it's loading:

Finally, get rid of the route import in the file to fully disconnect the demo bundle:

Refresh your browser. Yes, an error! No, I'm serious, this is good - it's telling us that the page can't be found. The demo page that was here a second ago is gone. Congratulations on your completely fresh Symfony project.

Setting up Git

Let's make our first commit! We're going to use git but not much is different if you use something else. If you don't use version control, shame!

If you already have a directory, get rid of it! Otherwise, you'll inherit the history from Symfony's standard distribution, which is about 1000 commits.

Create a new repository with :

Now don't go crazy with adding files: there are some things that we don't want to commit. Fortunately, Symfony gives us a solid file to start with.

The file is generated when you run Composer. It's super important, though you'll never need to look at it. Regardless, since it's generated automatically, we don't need to commit it.

The and directories also have generated contents, so we should ignore those too.

The file holds all server-specific config, like your database username and password. By ignoring it, each developer can keep their own version of the file.

To make life easier, we do commit an example version of the file called . That way, a new dev can actually create their file, without guessing what it needs to look like.

We also ignore the directory, because Composer downloads everything in here for us. If a new dev clones the code, they can just run and bam, their directory looks just like yours.

Everything is being ignored nicely so let's go crazy and add everything to git and commit:


Unless you want to accidentally commit vacation photos and random notes files, don't run try to avoid running , or at least run before committing.

Find some friends! It's time to celebrate the first to your awesome project. Do some jumping high fives, grab a pint, and make a Chewbacca cry.


There has been a lot of talk about document databases and how applicable they are for Web 2.0 application development. There are a bunch of projects in the “NoSQL” realm that are making a lot of noise, CouchDB, Cassandra, and MongoDB are the ones that are most mentioned. MongoDB is a scalable document database, which is also open source.

Part of our business is to develop internal applications and  support customers, so we dedicate a good amount of time to research, test and learn new technologies. We have been following this whole movement and decided to give MongoDB a try.

What has really taken our attention regarding MongoDB is its simplicity, yet how powerful it is. It lowers the barrier to develop DB-driven applications even more.

In MongoDB there are no tables and rows. You have collections and documents instead. And collections can contain any type of document, it is not limited by the columns or fields like a table. In some scenarios, this is a really big plus. Yet, some people, mostly those born and raised with RDBMS will be scared to death due to the lack of schema and rigid structures. As always, if you plan ahead and do your homework and design your entities properly, you will be fine.

Since collections can have different types of documents, let’s say, an array, you can update the document with more fields in the array. In the RDBM world to do this, you have to change your schema, making application upgrades one of the biggest pains.

Using MongoDB and PHP

To get started with MongoDB and PHP, you need to download and install the server. From the website you can download packages for your preferred OS or you can download the source and compile it. Installation is really simple. Once you have the files in your computer, to start the server all you have to do is run the daemon, ie.:

# /usr/local/mongodb/bin/mongod

MongoDB will start and initialize its DB storage.

Now you can connect with the mongo command line client or other clients like MongoHub, PHPMOAdmin among others.

To connect to MongoDB from PHP, you will need to install the mongo pecl extension. On Mac OS X or Linux, run:

# pecl install mongo

Then add the following line to php.ini and restart your web server:

The site has a very good tutorial on how to get started with MongoDB and PHP. Basically, to store something in MongoDB you follow these simple steps:

// connect to the default DB server, localhost $connection = new Mongo(); // select a DB $db = $connection->dbname; // get a collection, if it does not exist, it will get created $collection = $db->users; // insert a document $collection->insert( $doc );

That’s it! No table creation, nice! For more information on how to retrieve data, go to the tutorial.
MongoDB stores data in a binary JSON format. If you are familiar with JavaScript, you will know JSON. When you store a PHP object, when it is time to get the data from the DB, you will get an array instead. For many uses, this is OK, but some times, for more complex solutions, objects are necessary. Fortunately there is a solution already!

Enter ODM (Object Document Mapper)

ODM is a new project created by Jon Wage, a core developer of the popular Doctrine ORM. The Doctrine\ODM namespace will be the home to PHP 5.3 object mappers for Document based storage systems like MongoDB. Currently only the Doctrine\ODM\MongoDB code has been implemented and it will map PHP objects with MongoDB documents. So when you store PHP objects in MongoDB and you need to retrieve them, you will get back PHP objects. Not only that, but it also helps with relations between objects. The project home page includes a basic usage manual and a full working example.

What’s really nice about this solution is how unintrusive it is. Your classes are pure PHP classes without having to extend other classes. The only requirement is that you map your properties using one of the support metadata drivers. In this example we use the AnnotationDriver:

Take a look at the DocBlocks and how we map the properties to the document.

Once you defined your entities, the usage is super simple:

require '/path/to/doctrine/lib/Doctrine/Common/ClassLoader.php'; use Doctrine\Common\ClassLoader, Doctrine\Common\Annotations\AnnotationReader, Doctrine\ODM\MongoDB\Mongo, Doctrine\ODM\MongoDB\Configuration, Doctrine\ODM\MongoDB\Mapping\Driver\AnnotationDriver, Doctrine\ODM\MongoDB\Mapping\Driver\YamlDriver, Doctrine\ODM\MongoDB\EntityManager; $classLoader = new ClassLoader('Doctrine\ODM', __DIR__ . '/../lib'); $classLoader->register(); $classLoader = new ClassLoader('Doctrine', '/path/to/doctrine/lib'); $classLoader->register(); $classLoader = new ClassLoader('Entities', __DIR__); $classLoader->register(); $config = new Configuration(); $reader = new AnnotationReader(); $reader->setDefaultAnnotationNamespace('Doctrine\ODM\MongoDB\Mapping\Driver\\'); $config->setMetadataDriverImpl(new AnnotationDriver($reader, __DIR__ . '/Entities')); $em = EntityManager::create(new Mongo(), $config); $user = new User(); $user->username = 'jwage'; $user->password = 'changeme'; $user->profile = new Profile(); $user->profile->firstName = 'Jonathan'; $user->profile->lastName = 'Wage'; $user->account = new Account(); $user->account->name = 'Test Account'; $em->persist($user); $em->flush();

For more information, visit the project home page. Please note that this project is in very early stages of development, so things may change.

MongoDB, ODM and symfony

We will demonstrate how to use MongoDB with ODM and symfony. Symfony 2 is still in alpha stage, so even though it would be a perfect fit with ODM, we will stick with symfony 1.4 for now. For this part of the article, you will need to know a little bit of symfony.

1. If you don’t have a symfony project, go ahead and create it with ./symfony generate:project myproject

2. Download Doctrine2 (you will need the new class autoloader) and ODM into myproject/lib/vendor

3. Add the class auotoloader to the config/ProjectConfiguration.class.php file:

require_once __DIR__.'/../lib/vendor/symfony/lib/autoload/sfCoreAutoload.class.php'; sfCoreAutoload::register(); require __DIR__.'/../lib/vendor/doctrine2/lib/Doctrine/Common/ClassLoader.php'; use Doctrine\Common\ClassLoader, Doctrine\ODM\MongoDB\EntityManager; class ProjectConfiguration extends sfProjectConfiguration { public function setup() { $classLoader = new ClassLoader('Doctrine\ODM', __DIR__ . '/../lib/vendor/odm/lib'); $classLoader->register(); $classLoader = new ClassLoader('Doctrine\ODM', __DIR__ . '/../lib/vendor/doctrine2/lib'); $classLoader->register(); $classLoader = new ClassLoader('Entities', __DIR__.'/../lib'); $classLoader->register(); } }

4. Create your classes in lib/Entities, ie. lib/Entities/Server.php:

5. Now you can perform your operations, just to keep it simple, we will add the code to the

And your indexSuccess.php has nothing special about ODM:

Servers: <ul> <?php foreach( $servers as $s): ?> <li><?php echo esc_entities($s);?></li> <?php endforeach; ?> </ul>

Hopefully with this preview, you can see the power of MongoDB when joined by ODM and symfony.

Special thanks to Jon Wage for leading the development of this project and his contribution to this article.

0 thoughts on “Symfony2 Tutorial 6 Homework

Leave a Reply

Your email address will not be published. Required fields are marked *