Making all Services Private

Video not working?

It looks like your browser may not support the H264 codec. If you're using Linux, try a different browser or try installing the gstreamer0.10-ffmpeg gstreamer0.10-plugins-good packages.

Thanks! This saves us from needing to use Flash or encode videos in multiple formats. And that let's us get back to making more videos :). But as always, please feel free to message us.

There is one more key that lives under _defaults in a new Symfony 3.3 project: public: false:

... lines 1 - 8
services:
_defaults:
... lines 11 - 12
public: false
... lines 14 - 42

The idea of public versus private services is not new in Symfony 3.3... but defaulting all services to private is new, and it's a critical change. Thanks to this, every service in this file is now private. What does that mean? One simple thing: when a service is private, you cannot fetch it directly from the container via $container->get(). So, for example, $container->get('AppBundle\Service\MarkdownTransformer') will not work.

Tip

In Symfony 3.3, sometimes you can fetch a private service directly from the container. But doing this has been deprecated and will be removed in Symfony 4.

But, everything else works the same: I can pass this service as an argument and it can be autowired into an argument. Only the $container->get() usage changed.

In our app, making this change is safe! We just created all of these service ids a minute ago and they're not being used anywhere yet, definitely not with $container->get(). The exception is the last two services: we might be fetching these services directly from the container. And in fact, I know we are: in src/AppBundle/Controller/Admin/GenusAdminController.php. Down in editAction(), we're fetching both services via $this->get(), which is a shortcut for $this->container->get():

... lines 1 - 15
class GenusAdminController extends Controller
{
... lines 18 - 63
public function editAction(Request $request, Genus $genus)
{
... lines 66 - 69
if ($form->isSubmitted() && $form->isValid()) {
... lines 71 - 76
$this->addFlash(
'success',
$this->get('app.encouraging_message_generator')->getMessage()
);
... lines 81 - 84
} elseif ($form->isSubmitted()) {
$this->addFlash(
'error',
$this->get('app.discouraging_message_generator')->getMessage()
);
}
... lines 91 - 94
}
}

That means, for now, to keep our app working, add public: true under each service:

... lines 1 - 8
services:
... lines 10 - 30
app.encouraging_message_generator:
... lines 32 - 34
public: true
... line 36
app.discouraging_message_generator:
... lines 38 - 40
public: true

Aliases can also be private... but in legacy_aliases.yml, there is no _defaults key with public: false. So, these are all public aliases... which is exactly what we want, ya know, because we're trying not to break our app!

Like with every step so far, our app should still work fine. Woohoo! But... you may be wondering why we made the services private. Doesn't this just make our services harder to use? As we'll learn soon, when you use private services, it becomes impossible to make a mistake and accidentally reference a non-existent service. Private services are going to make our app even more dependable than before. And also, a little bit faster.

Next, let's talk about the biggest change to this file: auto-registration of all classes in src/AppBundle as services. Woh.

Leave a comment!

What PHP libraries does this tutorial use?

// composer.json
{
    "require": {
        "php": ">=5.5.9",
        "symfony/symfony": "3.3.0-RC1", // v3.3.0-RC1
        "doctrine/orm": "^2.5", // v2.7.2
        "doctrine/doctrine-bundle": "^1.6", // 1.6.8
        "doctrine/doctrine-cache-bundle": "^1.2", // 1.3.0
        "symfony/swiftmailer-bundle": "^2.3", // v2.6.2
        "symfony/monolog-bundle": "^3.1", // v3.1.0
        "symfony/polyfill-apcu": "^1.0", // v1.3.0
        "sensio/distribution-bundle": "^5.0", // v5.0.22
        "sensio/framework-extra-bundle": "^3.0.2", // v3.0.26
        "incenteev/composer-parameter-handler": "^2.0", // v2.1.2
        "knplabs/knp-markdown-bundle": "^1.4", // 1.5.1
        "doctrine/doctrine-migrations-bundle": "^1.1", // v1.2.1
        "stof/doctrine-extensions-bundle": "^1.2" // v1.2.2
    },
    "require-dev": {
        "sensio/generator-bundle": "^3.0", // v3.1.4
        "symfony/phpunit-bridge": "^3.0", // v3.2.8
        "nelmio/alice": "^2.1", // v2.3.1
        "doctrine/doctrine-fixtures-bundle": "^2.3" // 2.3.0
    }
}