Learn Symfony2 - part 2: Empty application 25/06/2014
Deprecated: This series has been re-written - see The Ultimate Developer Guide to Symfony
This is the second article of the series on learning the Symfony2 framework. Have a look at the first one: Composer.
In the first article we began to create an empty project with the following files:
.
├── composer.json
├── composer.lock
└── .gitignore
Running composer install
should create a vendor
directory, which we ignored
in git.
Here's the repository where you can find the actual code.
We'll now see how to create an empty Symfony2 application.
The front controller
First things first, we will create an index file which will act as a front controller: it will be the only entry point of our application and will decide which page to display.
Create its directory:
mkdir web
Then the file:
<?php
// File: web/app.php
use Symfony\Component\HttpFoundation\Request;
require_once __DIR__.'/../vendor/autoload.php';
require_once __DIR__.'/../app/AppKernel.php';
$kernel = new AppKernel('prod', false);
$request = Request::createFromGlobals();
$response = $kernel->handle($request);
$response->send();
$kernel->terminate($request, $response);
First it includes Composer's autoloader: it will require every files needed.
Then we create an instance of our Kernel with the production environment and the debug utilities disabled. This class acts like a web server: it takes a HTTP request as input and returns a HTTP response as output.
Request::createFromGlobals()
creates a representation of the HTTP request.
It is filled from PHP's variable super globals ($_GET
, $_POST
, etc).
The kernel then handles the request. To keep explanations short, let's simply
say that it will find the controller associated to the requested URL. It is the
controller's responsibility to return a representation of the HTTP response (see
Symfony\Component\HttpFoundation\Response
).
The $response->send()
method will simply call the PHP header
function and
print a string representing the response's body (usually HTML, JSON or anything
you want).
Finally the $kernel->terminate()
method will call any tasks which registered
to the kernel.terminate
event. This alows you to return a response as fast as
possible and then execute some actions like sending emails.
Note: events aren't in the scope of this article, but they're worth mentioning.
Creating the application's kernel
The HttpKernel component
provides you with a Kernel
class, which we will extend.
Create the following directory:
mkdir app
And then the kernel file:
<?php
// File: app/AppKernel.php
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\Config\Loader\LoaderInterface;
class AppKernel extends Kernel
{
public function registerBundles()
{
return array(
new Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
);
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load(__DIR__.'/config/config.yml');
}
}
This class will load the project's configuration. This is also where you register the project's bundles. We'll talk more about bundles in the next article, for now the only thing you need to know is that they're like plugins.
The Kernel has the responsibility to look at every registered bundle to retrieve their configuration.
The FrameworkBundle
defines some services and allows you to choose what to
enable via configuration.
Note: Services are objects which do one thing and do it well. They provide exactly what they're called: a service. We'll learn more about them in one of the next article.
We need to put some configuration in order to be able to make it work properly.
Create its directory:
mkdir app/config
And the the YAML file:
# File: app/config/config.yml
framework:
secret: "Three can keep a secret, if two of them are dead."
The secret
parameter is used as a seed to generate random strings (for e.g.
CSRF tokens).
Now that we have our application structure, let's commit it:
git add -A
git commit -m 'Created application structure'
Logs and cache
You'll also need to create logs
and cache
directories:
mkdir app/{cache,logs}
touch app/{cache,logs}/.gitkeep
Git doesn't allow to commit empty directory, hence the .gitkeep
files.
Because files in these directories are temporaries, we'll ignore them:
echo '/app/cache/*' >> .gitignore
echo '/app/logs/*' >> .gitignore
git add -A
git add -f app/cache/.gitkeep
git add -f app/logs/.gitkeep
git commit -m 'Created temporary directories'
Apache configuration
In order for your website to be browsed, you'll need to configure your web server. This configuration is well explained in the documentation, so here's a dump of an apache vhost:
<VirtualHost *:80>
ServerName knight.local
DocumentRoot /home/loic.chardonnet/Projects/gnugat/knight/web
ErrorLog "/home/loic.chardonnet/Projects/gnugat/knight/app/logs/apache_errors.log"
CustomLog "/home/loic.chardonnet/Projects/gnugat/knight/app/logs/apache_accesses.log" common
<Directory /home/loic.chardonnet/Projects/gnugat/knight/web>
Options Indexes FollowSymLinks MultiViews
AllowOverride None
Order allow,deny
allow from all
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /app.php [QSA,L]
</IfModule>
</Directory>
</VirtualHost>
If you run into some permission problem (like writing in cache
and logs
),
you might consider to change APACHE_RUN_USER
and APACHE_RUN_GROUP
environment variables present in /etc/apache2/envvars
to your own user and
group.
Conclusion
A Symfony2 application follows this pattern: a front controller associate an URL to a controller which takes a HTTP request and returns a HTTP response.
The next article will be all about bundles, so stay tuned :) .