Day 1: Starting up the Project
- This Book is different
- What for Today?
- Symfony Installation
- Project Setup
- Web Server Configuration: The ugly Way
- Web Server Configuration: The secure Way
- The Environments
- Final Thoughts
The symfony framework has been an Open-Source project for more than four years and has become one of the most popular PHP frameworks thanks to its great features and great documentation.
This book describes the creation of a web application with the symfony framework, step-by-step from the specifications to the implementation. It is targeted at beginners who want to learn symfony, understand how it works, and also learn about the best web development practices.
The application to be designed could have been yet another blog engine. But we want to use symfony on a useful project. The goal is to demonstrate that symfony can be used to develop professional applications with style and little effort.
We will keep the content of the project secret for another day as we already have much for now. However, let's give it a name: Jobeet.
Each day of this book is meant to last between one and two hours, and will be the occasion to learn symfony by coding a real website, from start to finish. Every day, new features will be added to the application, and we'll take advantage of this development to introduce you to new symfony functionalities as well as good practices in symfony web development.
Remember the early days of PHP4. Ah, la Belle Epoque! PHP was one of the first languages dedicated to the web and one of the easiest to learn.
But as web technologies evolve at a very fast pace, web developers need to keep up with the latest best practices and tools. The best way to learn is of course by reading blogs, tutorials, and books. We have read a lot of these, be they written for PHP, Python, Java, Ruby, or Perl, and many of them fall short when the author starts giving snippets of codes as examples.
You are probably used to reading warnings like:
"For a real application, don't forget to add validation and proper error handling."
"Security is left as an exercise to the reader."
"You will of course need to write tests."
What? These things are serious business. They are perhaps the most important part of any piece of code. And as a reader, you are left alone. Without these concerns taken into account, the examples are much less useful. You cannot use them as a good starting point. That's bad! Why? Because security, validation, error handling, and tests, just to name a few, take care to code right.
In this book, you will never see statements like those as we will write tests, error handling, validation code, and be sure we develop a secure application. That's because symfony is about code, but also about best practices and how to develop professional applications for the enterprise. We will be able to afford this luxury because symfony provides all the tools needed to code these aspects easily without writing too much code.
Validation, error handling, security, and tests are first-class citizens in symfony, so it won't take us too long to explain. This is just one of many reasons why to use a framework for "real life" projects.
All the code you will read in this book is code you could use for a real project. We encourage you to copy and paste snippets of code or steal whole chunks.
We won't write PHP code. But even without writing a single line of code, you will start understanding the benefits of using a framework like symfony, just by bootstrapping a new project.
The objective of this day is to setup the development environment and display a page of the application in a web browser. This includes installation of symfony, creation of an application, and web server configuration.
As this book will mostly focus on the symfony framework, we will assume that you already have a solid knowledge of PHP 5 and Object Oriented programming.
Before installing symfony, you need to check that your computer has everything installed and configured correctly. Take the time to conscientiously read this day and follow all the steps required to check your configuration, as it may save your day further down the road.
First of all, you need to check that your computer has a friendly working environment for web development. At a minimum, you need a web server (Apache, for instance), a database engine (MySQL, PostgreSQL, SQLite, or any PDO-compatible database engine), and PHP 5.2.4 or later.
The symfony framework comes bundled with a command line tool that automates a
lot of work for you. If you are a Unix-like OS user, you will feel right at
home. If you run a Windows system, it will also work fine, but you will just
have to type a few commands at the
As PHP configurations can vary a lot from one OS to another, or even between different Linux distributions, you need to check that your PHP configuration meets the symfony minimum requirements.
First, ensure that you have PHP 5.2.4 at a minimum installed by using the
phpinfo() built-in function or by running
php -v on the command line. Be
aware that on some configurations, you might have two different PHP versions
installed: one for the command line, and another for the web.
Then, download the symfony configuration checker script at the following URL:
Save the script somewhere under your current web root directory. Launch the configuration checker script from the command line:
$ php check_configuration.php
If there is a problem with your PHP configuration, the output of the command will give you hints on what to fix and how to fix it.
You should also execute the checker from a browser and fix the issues it might
discover. That's because PHP can have a distinct
php.ini configuration file
for these two environments, with different settings.
Don't forget to remove the file from your web root directory afterwards.
Before installing symfony, you first need to create a directory that will host all the files related to Jobeet:
$ mkdir -p /home/sfprojects/jobeet $ cd /home/sfprojects/jobeet
Or on Windows:
c:\> mkdir c:\development\sfprojects\jobeet c:\> cd c:\development\sfprojects\jobeet
Windows users are advised to run symfony and to setup their new project in a
path which contains no spaces. Avoid using the
Documents and Settings
directory, including anywhere under
If you create the symfony project directory under the web root directory, you won't need to configure your web server. Of course, for production environments, we strongly advise you to configure your web server as explained in the web server configuration section.
Now, you need to install symfony. As the symfony framework has several stable versions, you need to choose the one you want to install by reading the installation page on the symfony website.
This book assumes you want to install symfony 1.3 or symfony 1.4.
You can install symfony globally on your machine, or embed it into each of your project. The latter is the recommended one as projects will then be totally independent from each others. Upgrading your locally installed symfony won't break some of your projects unexpectedly. It means you will be able to have projects on different versions of symfony, and upgrade them one at a time as you see fit.
As a best practice, many people install the symfony framework files in the
lib/vendor project directory. So, first, create this directory:
$ mkdir -p lib/vendor
Installing from an Archive
The easiest way to install symfony is to download the archive for the version you choose from the symfony website. Go to the installation page for the version you have just chosen, symfony 1.4 for instance.
Under the "Source Download" section, you will find the archive in
.zip format. Download the archive, put it under the freshly created
lib/vendor/ directory, un-archive it, and rename the directory to
$ cd lib/vendor $ tar zxpf symfony-1.4.0.tgz $ mv symfony-1.4.0 symfony $ rm symfony-1.4.0.tgz
Under Windows, unzipping the zip file can be achieved using Windows Explorer.
After you rename the directory to
symfony, there should be a directory
structure similar to
Installing from Subversion (recommended)
If you use Subversion, it is even better to use the
svn:externals property to
embed symfony into your project in the
$ svn pe svn:externals lib/vendor/
Importing your project in a new Subversion repository is explained at the end of this day.
If everything goes well, this command will run your favorite editor to give you the opportunity to configure the external Subversion sources.
On Windows, you can use tools like TortoiseSVN to do everything without the need to use the console.
If you are conservative, tie your project to a specific release (a subversion tag):
Whenever a new release comes out (as announced on the symfony blog), you will need to change the URL to the new version.
If you want to go the bleeding-edge route, use the 1.4 branch:
Using the branch makes your project benefits from the bug fixes automatically
whenever you run a
Now that symfony is installed, check that everything is working by using the
symfony command line to display the symfony version (note the capital
$ cd ../.. $ php lib/vendor/symfony/data/bin/symfony -V
c:\> cd ..\.. c:\> php lib\vendor\symfony\data\bin\symfony -V
If you are curious about what this command line tool can do for you, type
symfony to list the available options and tasks:
$ php lib/vendor/symfony/data/bin/symfony
c:\> php lib\vendor\symfony\data\bin\symfony
The symfony command line is the developer's best friend. It provides a lot of utilities that improve your productivity for day-to-day activities like cleaning the cache, generating code, and much more.
In symfony, applications sharing the same data model are regrouped into projects. For most projects, you will have two different applications: a frontend and a backend.
sfprojects/jobeet directory, run the symfony
to actually create the symfony project:
$ php lib/vendor/symfony/data/bin/symfony generate:project jobeet --orm=Propel
c:\> php lib\vendor\symfony\data\bin\symfony generate:project jobeet --orm=Propel
generate:project task generates the default structure of directories and
files needed for a symfony project:
||Hosts all project applications|
||The files cached by the framework|
||The project configuration files|
||The project libraries and classes|
||The framework log files|
||The installed plugins|
||The unit and functional test files|
||The web root directory (see below)|
Why does symfony generate so many files? One of the main benefits of using a full-stack framework is to standardize your developments. Thanks to symfony's default structure of files and directories, any developer with some symfony knowledge can take over the maintenance of any symfony project. In a matter of minutes, he will be able to dive into the code, fix bugs, and add new features.
generate:project task has also created a
symfony shortcut in the project
root directory to shorten the number of characters you have to write when
running a task.
So, from now on, instead of using the fully qualified path to the symfony
program, you can use the
Now, create the frontend application by running the
$ php symfony generate:app frontend
Because the symfony shortcut file is executable, Unix users can replace all
occurrences of '
php symfony' by '
./symfony' from now on.
On Windows you can copy the '
symfony.bat' file to your project and use
symfony' instead of '
c:\> copy lib\vendor\symfony\data\bin\symfony.bat .
Based on the application name given as an argument, the
creates the default directory structure needed for the application under the
||The application configuration files|
||The application libraries and classes|
||The application code (MVC)|
||The global template files|
By default, the
generate:app task has secured our application from the two
most widespread vulnerabilities found on the web. That's right, symfony
automatically takes security measures on our behalf.
To prevent XSS attacks, output escaping has been enabled; and to prevent CSRF attacks, a random CSRF secret has been generated.
Of course, you can tweak these settings thanks to the following options:
--escaping-strategy: Enables or disables output escaping
--csrf-secret: Enables session tokens in forms
Before trying to access your newly created project, you need to set the write
permissions on the
log/ directories to the appropriate levels, so
that your web server can write to them:
$ chmod 777 cache/ log/
Tips for People using a SCM Tool
symfony only ever writes in two directories of a symfony project,
log/. The content of these directories should be ignored
by your SCM (by editing the
svn:ignore property if you use Subversion
If you have created the project directory it somewhere under the web root directory of your web server, you can already access the project in a web browser.
Of course, as there is no configuration, it is very fast to set up, but try to
config/databases.yml file in your browser to understand the bad
consequences of such a lazy attitude. If the user knows that your website is
developed with symfony, he will have access to a lot of sensitive files.
Never ever use this setup on a production server, and read the next section to learn how to configure your web server properly.
A good web practice is to put under the web root directory only the files that
By default, we recommend to store these files under the
web/ sub-directory of
a symfony project.
If you have a look at this directory, you will find some sub-directories for web
images/) and the two front controller files. The
front controllers are the only PHP files that need to be under the web root
directory. All other PHP files can be hidden from the browser, which is a good
idea as far as security is concerned.
Now it is time to change your Apache configuration, to make the new project accessible to the world.
Locate and open the
httpd.conf configuration file and add the following
configuration at the end:
# Be sure to only have this line once in your configuration NameVirtualHost 127.0.0.1:8080 # This is the configuration for your project Listen 127.0.0.1:8080 <VirtualHost 127.0.0.1:8080> DocumentRoot "/home/sfprojects/jobeet/web" DirectoryIndex index.php <Directory "/home/sfprojects/jobeet/web"> AllowOverride All Allow from All </Directory> Alias /sf /home/sfprojects/jobeet/lib/vendor/symfony/data/web/sf <Directory "/home/sfprojects/jobeet/lib/vendor/symfony/data/web/sf"> AllowOverride All Allow from All </Directory> </VirtualHost>
to properly display default symfony pages and the web debug toolbar|Web Debug Toolbar.
On Windows, you need to replace the
Alias line with something like:
Alias /sf "c:\dev\sfprojects\jobeet\lib\vendor\symfony\data\web\sf"
/home/sfprojects/jobeet/web should be replaced with:
This configuration makes Apache listen to port
8080 on your machine, so,
after restarting apache, the website will be accessible at the following URL:
You can change
8080 to any number, but favour numbers greater than
they do not require administrator rights.
Configure a dedicated Domain Name
If you are an administrator on your machine, it is better to setup
virtual hosts instead of adding a new port each time you start a new
project. Instead of choosing a port and add a
choose a domain name (for instance the real domain name with
.localhost added at the end) and add a
# This is the configuration for your project <VirtualHost 127.0.0.1:80> ServerName www.jobeet.com.localhost <!-- same configuration as before --> </VirtualHost>
The domain name
www.jobeet.com.localhost used in the Apache configuration
has to be declared locally. If you run a Linux system, it has to be
done in the
/etc/hosts file. If you run Windows XP, this file is
located in the
Add in the following line:
Restart Apache, and check that you now have access to the new application by
opening a browser and typing
http://www.jobeet.com.localhost/index.php/ depending on the Apache
configuration you chose in the previous section.
If you have the Apache
mod_rewrite module installed, you can remove
index.php/ part of the URL. This is possible thanks to the
rewriting rules configured in the
You should also try to access the application in the development environment (see the next section for more information about environments). Type in the following URL:
The web debug toolbar should show in the top right corner, including small icons
proving that your
sf/ alias configuration is correct.
The setup is a little different if you want to run symfony on an IIS server in a Windows environment. Find how to configure it in the related tutorial.
If you have a look at the
web/ directory, you will find two PHP files:
frontend_dev.php. These files are called front
controllers; all requests to the application are made through them. But why do
we have two front controllers for each application?
Both files point to the same application but for different environments. When you develop an application, except if you develop directly on the production server, you need several environments:
The development environment: This is the environment used by web developers when they work on the application to add new features, fix bugs, ...
The test environment: This environment is used to automatically test the application.
The staging environment: This environment is used by the customer to test the application and report bugs or missing features.
The production environment: This is the environment end users interact with.
What makes an environment unique? In the development environment for instance, the application needs to log all the details of a request to ease debugging, but the cache system must be disabled as all changes made to the code must be taken into account right away. So, the development environment must be optimized for the developer. The best example is certainly when an exception occurs. To help the developer debug the issue faster, symfony displays the exception with all the information it has about the current request right into the browser:
But on the production environment, the cache layer must be activated and, of course, the application must display customized error messages instead of raw exceptions. So, the production environment must be optimized for performance and the user experience.
If you open the front controller files, you will see that their content is the same except for the environment setting:
// web/index.php <?php require_once(dirname(__FILE__).'/../config/ProjectConfiguration.class.php'); $configuration = ProjectConfiguration::getApplicationConfiguration('frontend', 'prod', false); sfContext::createInstance($configuration)->dispatch();
The web debug toolbar is also a great example of the usage of environment. It is present on all pages in the development environment and gives you access to a lot of information by clicking on the different tabs: the current application configuration, the logs for the current request, the SQL statements executed on the database engine, memory information, and time information.
It is a good practice to use source version control when developing a web application. Using a source version control allows us to:
- work with confidence
- revert to a previous version if a change breaks something
- allow more than one person to work efficiently on the project
- have access to all the successive versions of the application
In this section, we will describe how to use Subversion with symfony. If you use another source code control tool, it must be quite easy to adapt what we describe for Subversion.
We assume you have already access to a Subversion server and can access it via HTTP.
If you don't have a Subversion server at your disposal, you can create a repository for free on Google Code or just type "free subversion repository" in Google to have a lot more options.
First, create a repository for the
jobeet project on the repository server:
$ svnadmin create /path/to/jobeet/repository
On your machine, create the basic directory structure:
$ svn mkdir -m "created default directory structure" http://svn.example.com/jobeet/trunk http://svn.example.com/jobeet/tags http://svn.example.com/jobeet/branches
And checkout the empty
$ cd /home/sfprojects/jobeet $ svn co http://svn.example.com/jobeet/trunk/ .
Then, remove the content of the
log/ directories as we don't want
to put them into the repository.
$ rm -rf cache/* log/*
Now, make sure to set the write permissions on the cache and logs directories to the appropriate levels so that your web server can write to them:
$ chmod 777 cache/ log/
Now, import all the files and directories:
$ svn add *
As we will never want to commit files located in the
directories, you need to specify an ignore list:
$ svn propedit svn:ignore cache
The default text editor configured for SVN should launch. Subversion must ignore all the content of this directory:
Save and quit. You're done.
Repeat the procedure for the
$ svn propedit svn:ignore log
Finally, commit these changes to the repository:
$ svn import -m "made the initial import" . http://svn.example.com/jobeet/trunk
Windows users can use the great TortoiseSVN client to manage their subversion repository.
Well, time is over! Even if we have not yet started talking about symfony, we have setup a solid development environment, we have talked about web development best practices, and we are ready to start coding.
Tomorrow, we will reveal what the application will do and talk about the requirements we need to implement for Jobeet.
This work is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.