Symfony 2 from the eyes of a ZFer
The time to create a new Apache virtual host and I'm up; I have downloaded the last release candidate of Symfony 2, as a standard package with bundled dependencies. I copy the contents in a Symfony/ folder in my document root: they weigh about 15 MB. I'm a Zend Framework user and ZF has grown to almost 100 MB - 15 MB are not a problem, space is cheap.
As the installation of Symfony 2, I load the configuration url which will check my strange php.ini settings; I was missing the timezone configuration in this development machine since I mostly use the command line and not PHP through Apache.
The in-browser setup reminds me a bit of an old-style CMS like Joomla and Drupal (heresy!), but indeed is going to simplify the life of end users. Symfony 2 also ships with a pre-generated folder structure:
- app: configuration of routes, security, cache... Fortunately it's all already there. There is nothing more frustrating than starting to code and find out that some configuration file in an esoteric format and markup language has to be created.
- src: the code of your bundles, typically controllers but also everything they use.
- vendor: libraries like Doctrine and Twig, but also the ones you will add. Everything is bundled (incredibly lame pun), and assembling these libraries from scratch would be lot of work.
- web: static files and front controllers, which I guess means this is the only directory to expose as document root. However, I see plenty of .htaccess files to stop HTTP clients from descending in private folders like src/.
Again I can compare this structure with Zend Framework (1.x), the other big player in the PHP realm. Usually this structure is generated by Zend_Tool called via command line, and there is an additional step where zf has to be set up. The Symfony experience skips this problematic step.
The MVC stack
The Model-View-Controller stack is one of the primary reasons for adopting a PHP framework: otherwise you're just using a library.
Controllers are very similar to Zend Framework ones: they are classes with a list of actions, which take a request object and produce a response. The same Action Controller pattern is still with us.
The use of the render method is also an analogue:
render() returns the response, which in turn must always be returned by the action: it's a clear contract. There's also an Api for accessing the request object and the session, and a bundled flash message helper.
By the way, I discovered the @Template() annotation can be inserted for rendering automatically a template instead of explicitly call render(). In this case, the action just returns an array of view data instead of a response object.
Templates are written in Twig, but it's only the default: not an imposition on you. In the same way, Yaml is only the default for configuration, and you can choose plain PHP code.
Routing seems a bit more complex than the rest of the MVC stack, but I guess I just have to dive into it a little more:
- the controller to use for a certain pattern or prefix is configured via ClassNameController::methodName, or by shortening this to Namespace:BaseClassName:Action.
- in general, resources defined with logical names shortened by convention instead of full path. It's a little indirection over physical files that may come handy.
Routes may also be defined as annotations on the controller methods: all this use of annotations reminds me of Doctrine 2, which is indeed bundled as the default ORM.
What I like (and I am a ZFer)
First of all code, both the vendor and the application one, is organized in bundles: I'm glad there is now a formal unit defined over folders or namespaces.
Second, the command line console just works, from every folder:
This behavior is not easy to get right with a tarball installation, but Symfony does.
Third, performance is taken seriously: everything from configuration is cached, and it's pointed out. installing APC is also a suggestion in the initial configuration where you look at php.ini.
In any case, there is really great care in assembling the final package for ease of use and developer experience: the developer is followed in each step in configuration, and the first hard thing he needs to do is essential complexity, not accidental one: writing a new Action Controller.
ZF 2 will need something similar if it wants to stay together with Symfony given the better time to market of the latter: simplifying exceptions and transitioning to namespaces are good steps, but not really groundbreaking.