I of course know Symfony best, so that’s what I describe below. It would certainly be interesting if others make similar posts in their respective framework. I’m interrested to see them all side by side. (@K_Wolfe ;?)
I’m not sure which details you’re most interested in, so I’ll try to give an abbreviated summary of workflow in Symfony.
– Routes –
Routes can be defined with plain PHP, Yaml, XML, or annotations. Here’s a quick example of each (except XML, 'cause… bleh).
# plain PHP
$routeCollection->add('article_show', new Route('/articles/{slug}', array(
'_controller' => 'YourProjectBundle:Article:show',
)));
# Yaml
article_show:
path: /articles/{slug}
defaults: { _controller: YourProjectBundle:Article:show }
# Annotation
/**
* @Route("/articles/{slug}")
*/
public function showAction()
{
// ...
}
– Controllers –
In Symfony, a controller is any callable that accepts a request and returns a response.
public function showAction(Request $request)
{
// ...
return new Response();
}
Symfony provides a few convenience shortcuts. A controller’s arguments can be the route parameters, and a render method can render a template and compose the response.
public function showAction($slug)
{
// ...
return $this->render('YourProjectBundle:Article:show.html.twig', array(
'article' => $article
));
}
– Templates –
Templates in Symfony typically define blocks. They then “extend” another template that uses those blocks.
# show.html.twig
{% extends 'YourProjectBundle::layout.html.twig' %}
{% block title %}
{{ article.title }}
{% endblock %}
{% block body %}
<h2>{{ article.title }}</h2>
<p>{{ article.body }}</p>
<!-- output escaping happens automatically and by default
no xss vulnerabilities here -->
{% endblock %}
# layout.html.twig
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}Default Title{% endblock %}</title>
</head>
<body>
<div id="sidebar">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/blog">Blog</a></li>
</ul>
</div>
<div id="content">
{% block body %}{% endblock %}
</div>
</body>
</html>
Templates can also “include” other template snippets, or they can “render” (embed) the output from other controllers.
You also have the option to use plain PHP temlates if you choose.
Symfony also comes packaged with the Assetic library. JS and CSS can be automatically combined and minified in prod, and in dev they can be served separate and un-unminifed. Assetic can also compile SASS, LESS, and several others for you.
– Model –
Models in Symfony are separate from the persistence mechanism (such as a database). A model is made up of very simple classes.
class Article
{
private $title;
private $body;
}
How the entity classes behave and interact with each other is what defines your business logic.
To persist your entities (aka, save to database), Symfony comes packaged with the Doctrine ORM. (You also have the option of using Propel, or any other ORM, or no ORM). There are several ways you can tell Doctrine how to persist your entities.
# plain PHP
$metadata->mapField(array(
'fieldName' => 'title',
'columnName' => 'title', // optional if field and column names are the same
'type' => 'string'
));
# Yaml
Article:
type: entity
fields:
name: title
column: title
type: string
# Annotation
class Article
{
/**
* @ORM\\Column(name="title", type="string")
*/
private $title;
// ...
}
Then Doctrine can save and retrieve Article objects, and generate your schema.
– Testing –
Symfony isn’t tied to any particular testing framework, though the documentation examples do indeed use PHPUnit.
The Symfony profiler is also pretty stellar.
(More to come perhaps late tomorrow. Forms, validation, caching, security…)