A Symfony2 Primer

A Symfony2 Primer

Introduction

The purpose of this tutorial is to give a reasonably experienced PHP developer a quick tour of the PHP Framework Symphony2. There is plenty of information available to delve deeper into areas and/or solve particular problems you may encounter. It focuses on typical steps you would need to take in creating an application.

What do I need?

You probably already have a PHP development environment? At a minimum, you need a web server (Apache, for instance), a database engine (MySQL), and PHP 5.3.2 or later. You can do this within an XAMP, Oracle Virtual Box” or a suitable hosted ISP environment.

Download and install Symfony2

The easy way:

  1. Create a working folder outside your web root, e.g /var/home/doug
  2. Install ‘Composer’. Composer is a tool for dependency management in PHP. It installs and manages the dependent libraries your project needs.
    • curl -s http://getcomposer.org/installer | php
  3. Use ‘Composer’ to install Symfony and all its dependencies.
    • php composer.phar create-project symfony/framework-standard-edition path/to/install

That should be it.

If you prefer to be more ‘hands on’ go to http://symfony.com/download. Choose “Symfony Standard” (the version with vendors) and after downloading follow the installation instructions in the readme file.

Anatomy of a Symfony Installation

You will notice at step 3 above, you were able to specify the path to the installation folder. You probably already have a convenient workflow for your application development so put it where you like to work but bear in mind that one folder needs to be accessible to your web server.

Below is a suggested workflow to illustrate what the installation will look like.

  1. First create a home folder for all your projects, e.g
    • /var/www/projects
  2. Then create a subfolder for a particular project, e. g
    • /var/www/projects/myproject
  3. Use “/var/www/projects/myproject” as the installation path (Step 3 above). You will then see the following sub-folders appear:
    • app/: The application configuration folder.
    • src/: Your project’s PHP code – the files you work on most.
    • vendor/: The third-party dependencies/bundles like Doctrine, Twig, Composer and many more.
    • web/: The web root directory, the home of all public static files like images, stylesheets as well as the front controller to your application

Web Server Configuration

As a developer you know the only files in folders served by a web servers should be those you are prepared to make accessible to the world at large. Various bots/spiders crawl these folders so you can never be sure someone won’t be getting up to mischief.

In the Symfony development environment the only folder that needs to be served by the web server is the “web” folder. This is where publicly exposed assets (such as css,images,js) and front end controllers live. In my example although I have specified an installation path of “/var/www/projects/myproject”, I would only expose the web sub-folder (“/var/www/projects/myproject/web“) to the web server.

All functional access to other files is achieved through the front end controller located in the “web” folder. For me this is a convenient and secure arrangement.

You need to be able to manage your Apache2 configuration directives to specify the “DocumentRoot as shown below. I prefer to run up a virtual host for each application but you could experiment with your own configurations. For example.

ServerName myapp.domainname.com
DocumentRoot /var/www/projects/myproject/web

Set the default front end controller

DirectoryIndex app.php

Set up the various option for this directory (folder).
e.g
Directory /var/www/projects/myproject/web
AllowOverride All
Allow from All

The directives above are not complete just examples of the sort of thing you do. Don’t forget to restart your web server if you change the configuration.

Oh and one more thing

The folders “app/cache” and “app/logs” need to me writable by the apache user of your web server (you’ll notice these folders are not within the DocumentRoot but the apache user still needs to be able to write to them).

One issue is that the app/cache and app/logs folders may also need to be writable by the command line user, especially during the development process as you clear the cache and log files. On Ubuntu you can run the following command just once in your project to ensure that permissions will be setup properly and all users will be able to modify the files and directories within these folders.

sudo setfacl -dR -m u::rwX app/cache app/logs

This will work providing you have ACL enabled on your file system. If not you could do:

chown -R www-data:www-data app/cache and chown -R www-data:www-data app/logs and then chmod -R 775 to give everyone in the www-data group write permission to the folders.

To test your installation go to the URL:

http://myappdomainname.com/app_dev.php

If you are not accessing this from a ‘localhost’ setup will get a ‘You can’t access this page error’, as the default out of the box, security kicks in. Take a look at code at the start of app_dev.php and decide whats works best you. You can probably just comment out the code for now and decide what you want to do later. You should now see the Symfony2 default page. The app_dev.php is the controller you would use for development only. See the documentation to review the differences between the app.php and app_dev.php controllers but essentially they are the controllers for the production and development environments through which all access to your application is controlled. If you get this far you are ready to rock and roll.

Create Your First Project

The Symfony documentation refers to projects as being made up of “bundles”. For me at least this was confusing, as the word bundle means jack in the world of computer programming pre Symfony (as I said, to me at least). Why not ‘packages’ or ‘modules’?

I recall when I was learning Object Orientated Programming (OOP) and people started talking about ‘Objects’ – I had the same uneasy feeling about that word a well. This is an unnecessary distraction and can focus your attention away from what you need to learn. So if you are like me then think of a bundle as a series of folders related to some aspect of your project, mentally use the word “folder” instead. Eventually you get used to the word ‘bundle’ and start to appreciate the nuances of meaning that the word ‘bundle’ brings to the table.

All projects consist of bundles and even the Symfony framework itself is a bundle.

There is a command line interface, called the Console, php app/console that you will use for different manual tasks such as creating databases, generating the CRUD interface to tables and installing other ‘bundles’. Generally quite useful but a bit tedious to remember the syntax of the various options. To see a list of things it can do navigate to the project folder and enter:

php app/console list. Do this now to make sure everything is ok and you are ready to create a project.

Steps

  1. Use the console tool to generate the skeleton of your application/project. Think of a decent name because its harder to change it later.
  2. Generate your project skeleton by:
    php app/console generate:bundle --namespace=MyName/MyProjectBundle --format=yml
    where “MyName” and “MyProject” are up to you. The project skeleton will be created in a folder “src/MyName/MyProjectBundle” so pick names that make sense to you as these will appear as folders in the src folder.

  3. For example at Clarity we would use Clarity as the “MyName” and “MyProject” would be the name of the application or product.
  4. Now clear the “dev” and “app” environment cache
    • php app/console cache:clear --env=prod
    • and php app/console cache:clear --env=dev
  5. That’s it. Your own bundle can now be found in the src directory of the project: src/MyName/MyProjectBundle.
  6. Test the default action and controller at “http://yourdomain/hello/MyProject (‘hello’ is a default action created for you. Check your apache configuration if this doesn’t work)
  7. or http://yourdomain/app_dev.php/hello/MyProject should work too (case won’t matter as its a URL)

The bundle generator made a DefaultController with an index action.

Create a Database Table

You can create the database and tables with the console command. e.g
php app/console doctrine:database:create

You can create your data tables either in-line with the console command tool or using your favorite database tool such as phpmyadamin, mysqlworkbench or whatever. You can even create schema for your tables in various text file formats, including including YAML and have them processed from the command line (console). Read the documentation to see your options here, there are many.

The ORM

Having created your database you can use Doctrine to generate the classes (objects) from the database. These are classes used to persist data to the database. This is a topic for another day so you should chase up another reference as to why this is a good thing.

php app/console doctrine:generate:entities MyNameMyProjectBundle

This magically processes the yml files in the “src/MyName/MyProjectBundle/Resources/config/doctrine” folder.

You edit these files to describe the data tables your application needs. You can see how this works with the path to your src files (i.e src/MyName/MyProject becomes MyNameMyProject) and searching the “Resources/config” folders for yml files).

If this executes successfully you should see a folder call “Entity” appear in your “src/MyName/MyProject” folder and this is where the newly generated classes live. These connect the database to the code you use in your application to read/write (get or set) data. Instead of dealing with SQL you deal with objects – how good is that!

Doctrine generates the Classes but we also need to create the tables in the database. Do this with the console.  

php app/console doctrine:schema:update --force

This should only be done in the dev environment. For a more robust method of systematically updating your production database, read about 

Doctrine migrations.

Now generate a CRUD (create, read, update and delete) interface with:

php app/console doctrine:generate:crud --entity=MyNameMyProjectBundle:TABLENAMEHERE --route-prefix=ens_job --with-write --format=yml

We should now have a basic application up and running. If the URL to your controllers is not working check you have a controller for the action in your ‘Controller’ folder and route for it in the Config folder.

Templates

The controller is responsible for handling all requests that come to the application. The controller delegates work according to the various specified Routes and Actions. Actions generally return a Response Object and if these need to be rendered as HTML or other content served by the web server the controller will hand this work off to the template engine. The default template engine is Twig. This is the ‘View’ part in MVC architecture.

The console command:

php app/console assets:install web

Will copy the assets you created in your development folders “Resources/Public/{images,css,js}” to the public “web” folder (actually they end up in the “web/bundles” folder).