As Symfony 2.3 is going to be released today, let's review some enhancements that I haven't had time to write about yet.

Marco Pivetta
Contributed by Marco Pivetta in #7890

Lazy Services

The Symfony Dependency Injection Container has been stable for a very long time now, and the introduction of lazy services is probably the most important feature that has been added since 2.0.

What is it about? Whenever you get a service from the container, there is a cost. This cost is directly related to the number of dependencies the service has and the time it takes to create them. But some dependencies might take a very long time to initialize: think web service end points, database connections, mailer initialization, ...

To reduce the cost of creating a service, you might proxy the service to be able to execute the slow code as late as possible. As of 2.3, using lazy services is a built-in feature of the Symfony Dependency Injection Container. And using it is a breeze; just declare your service as being lazy:

1
2
3
4
services:
   foo:
     class: Acme\Foo
     lazy: true

So, why not declaring all services as being lazy? You can imagine that there are some drawbacks. Read the new chapter about lazy services to learn more.

Fabien Potencier
Contributed by Fabien Potencier in #7007

Synchronized services

When developers have a problem with the dependency injection container, this is often because they have a service that depends on the request. Why? Because the request is a bit special: it is only available during the handling of an HTTP request, and the instance changes if you have sub-requests; to take into account these specificities, the request is in a different scope, the request scope. That opens up a lot of potential problems. I won't expose them here, as most of them have been "fixed" in 2.3.

As of 2.3, if you inject the request via a setter, your service does not need to be in the request scope anymore, and Symfony will automatically call it whenever the request changes:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// src/Acme/HelloBundle/Mail/Mailer.php
namespace Acme\HelloBundle\Mail;

use Symfony\Component\HttpFoundation\Request;

class Mailer
{
    protected $request;

    public function setRequest(Request $request = null)
    {
        $this->request = $request;
    }

    public function sendEmail()
    {
        if (null === $this->request) {
            // throw an error?
        }

        // ... do something using the request here
    }
}

Whenever a request is entered or leaved, the service container will automatically call the setRequest() method with the current request instance.

You might have noticed that the setRequest() method accepts null as a valid value for the request argument. That's because when leaving the request scope, the request instance can be null (for the master request for instance).

The cookbook about scopes has been updated and it explains everything you should know about scopes and the request.

Jean-François Simon
Contributed by Jean-François Simon in #7463

CSS Selector

The CSS selector components had some limitations that were not easily fixable before 2.3. So, we decided to rewrite it from scratch but we kept the exact same API. You can now enjoy a better support for advanced CSS selectors and you can still use the same API.

Bernhard Schussek
Contributed by Bernhard Schussek in #7386

Internationalization

The intl PHP extension and the ICU library are great tools, but they are also a nightmare to install. To ease things a little bit, Bernhard created two new components: Icu and Intl.

The Intl component is a simple drop-in replacement layer for the C intl extension. Install it via Composer and have it available automatically if the intl extension is not available.

If the intl extension is installed, Composer will install the ICU data for the ICU version in the intl extension. If the intl extension is not installed, Composer will use stub ICU data for the latest ICU version.

As always, the official documentation is the best starting point.

Daniel Holmes
Contributed by Daniel Holmes in #790

Comparison Validators

This one took a loooooong time to be merged (the PR was one of the oldest one still opened: number 790). You can know use comparison constraints and validators:

  • EqualTo;
  • NotEqualTo;
  • IdenticalTo;
  • NotIdenticalTo;
  • LessThan;
  • LessThanOrEqual;
  • GreaterThan;
  • GreaterThanOrEqual.

Did I ever say that the documentation team is doing a wonderful job? Yep, all these new constraints are already documented.

Konstantin Myakshin
Contributed by Konstantin Myakshin in #6474

Fatal Error Logging

Nobody likes white pages, or blue ones for that matter. Whenever a fatal error occurs, you need to understand what happened... even in the production environment. That's why the logging of fatal errors in Symfony 2.3 is a small but very nice addition. And the best thing is that you don't need to do anything, it comes out of the box.

The End

That's the last blog post about Symfony 2.3 new features. Symfony 2.3 comes with even more goodness like form processors, a consistent Client implementation or custom template escaping guessers; but that's probably time to make a release now... Come back soon to celebrate the release of 2.3.

Published in #Living on the edge