Reading Simplyfing Django I was reminded of how we organize the Symfony2 Training at Qafoo to start with a very simple "Hello World" example.
The Symfony2 Standard Edition already contains a huge burden of concepts, assumptions and conventions that can be confusing for a beginner.
- YAML
- Twig
- Environments and Dependency Injection Container
- Various weird and magic syntaxes for bundles,
_controller
and template names - Various files to open and poke around in
- Composer
- Maybe even Doctrine
As a trainer it is very hard to explain all this at the same time. It makes a lot of sense to avoid as many of them as possible.
That is why the Standard Edition is not the best way to start teaching Symfony, but one should actually consider a much lighter version of the framework and then gradually add more and more features until you end up with the standard edition.
Fabien discussed the simplification of the Symfony Standard Edition from another angle before, considering the minimum necessary code to use when reproducing bugs in his blog post "Packing a Symfony Full-Stack Application in one file".
This blog post is about a truely minimal Symfony edition to start learning about the framework. The first thing I like to show is a really simple Hello World controller:
<?php
namespace Acme\TrainingBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
class HelloController
{
public function helloAction()
{
return new Response('Hello World!');
}
}
What is the necessary framework glue code to support this Hello World? Lets start from the index file `web/index.php`:
<?php
require_once __DIR__ . "/../vendor/autoload.php";
require_once __DIR__ . "/../app/AppKernel.php";
use Symfony\Component\HttpFoundation\Request;
$request = Request::createFromGlobals();
$kernel = new AppKernel('dev', true);
$kernel->handle($request)->send();
We are using Composer here and the AppKernel
class, lets take a peak
at them:
{
"require": {
"symfony/symfony": "@stable"
},
"autoload": {
"psr-0": { "Acme": "src/" }
}
}
The `composer.json` file installs the latest stable Symfony release and
adds autoloading for classes starting with Acme
in the folder `src`.
We need to define a Kernel for our application in `app/AppKernel.php` and the minimal version of this looks like:
<?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(),
new Symfony\Bundle\TwigBundle\TwigBundle(),
);
}
public function registerContainerConfiguration(LoaderInterface $loader)
{
$loader->load(function ($container) {
$container->loadFromExtension('framework', array(
'secret' => 'some secret here',
'router' => array(
'resource' => '%kernel.root_dir%/config/routing.yml'
),
'templating' => array('engines' => array('twig'))
));
});
}
}
In trainings we are starting with a single config.yml
file but that is
technically not necessary by using the ClosureLoader
. The routing
component has no such closure loader, so its not possible to avoid
YAML in the first minutes of Symfony2 exposure and we reference
the `app/config/routing.yml`:
hello:
pattern: /
defaults:
_controller: "Acme\TrainingBundle\Controller\HelloController::helloAction"
Did you know that you can specify controllers in Symfony by using the static callback
syntax? It has disadvantages when considering bundle inheritance, but why
bother a beginner with this feature and confuse him with the convention of
"AcmeTrainingBundle:Hello:hello"
.
There are still lots of trip wires to stumble upon in this simple piece of routing.yml
:
- Tabs are not allowed in YAML, in every training at least one person gets bitten by that.
- 2 vs 4 spaces ambiguity.
- What is this magic
_controller
key? - I carefully avoid the
{}
inline syntax of YAML here as well as it introduces yet another ambiguity.
Run this application with the build in webserver:
$ php -S localhost:8000 web/index.php
Hello World!
The next step for a beginner is his first twig template to print the Hello
World. To avoid another confusing convention at the beginning, the "AcmeTrainingBundle:Hello:hello.html.twig"
template syntax, you can make use of the `app/Resources/views/` folder
that is automatically registered in the Twig Bundle. Just create
a template `app/Resources/views/hello.html.twig` and change the controller:
<?php
namespace Acme\TrainingBundle\Controller;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class HelloController extends Controller
{
public function helloAction()
{
return $this->render('hello.html.twig');
}
}
The total number of files is 5 (6 with template) for this example. Note that we
haven't actually created a bundle for AcmeWorkshopBundle
yet, because with
the static syntax we don't need it.
This is a very good starting point to start exploring more features of Symfony and gradually add the required configuration and files for this.