Symfony 3.3 will introduce lots of features to simplify the way you work with services in your applications, such as simpler configuration and autoconfig. This article explains the last big feature related to Dependency Injection: PSR-4 based service discovery and registration.
The idea is to look for PHP classes in some given directories and register them
as services if their namespaces meet the PSR-4 naming syntax. This feature is
configured using the resource
option, which accepts a directory path or a
Glob expression to match multiple directories. Example:
1 2 3 4
services:
App\:
resource: ../src/{Controller,Command}
# ...
This config looks for PHP files in the src/Controller/
and src/Command/
directories of the application, infers the PSR-4 class names from those files
and uses class_exist()
to check that they exist before registering those
classes as Symfony services (using the class FQCN as the service id).
This feature is so convenient that Symfony Flex uses it by default in the
app.yaml
config file that will be used in Symfony 4 applications:
1 2 3 4 5 6 7 8 9 10 11
services:
# ...
# this creates a service per class whose id is the fully-qualified class name
App\:
resource: '../../src/{Command,Form,EventSubscriber,Twig,Security}'
App\Controller\:
resource: '../../src/Controller'
public: true
tags: ['controller.service_arguments']
If your application contains lots of directories, you can include all of them
using a *
value in the resource
option and then use the exclude
option to exclude some directories if needed:
1 2 3 4 5 6 7 8
services:
# ...
AppBundle\:
# discover services in all AppBundle/ sub-directories...
resource: '../../src/AppBundle/*'
# ... except in those matching this Glob expression
exclude: '../../src/AppBundle/{AppBundle.php,Entity}'
What about the dependencies of the services? Somehow it isn't clear to me, how the injection parameters are defined in this automatic scan - is autowiring turned on by default? What if the services use interfaces as a dependency?
Maybe it would be nice to mention the tiny details I'm asking about in the article as well.
@Martin, you just need to redefine your service.
@Martin yes, you may need some more config. Check the contents of the app.yaml file used by Symfony Flex: https://github.com/symfony/recipes/blob/master/symfony/framework-bundle/3.3/etc/packages/app.yaml
I love most of the work going on in Symfony at the moment, there's some great stuff in the pipeline for future version. However I'm not convinced these autowiring and FQCN-based service names changes are a wise idea. While it makes it easy to get up and running, understanding what is happening behind the scenes becomes quite confusing, then people are forced to learn the current way to define their services once things get too complex for the automatic methods to handle.
Can anyone explain to me the benefit of this change? Or is there a Github issue I could read? Genuine request.
awesome
Will this feature be in Symfony 3 certification questions?
I think it will break docker based structures that using Alpine Linux. Because Alpine doesn't support GLOB_BRACE since it is using musl libc instead of GNU libc.
https://bugs.php.net/bug.php?id=72095 http://ftp.grokbase.com/t/php/php-doc-bugs/164rneeqx3/php-bug-bug-72095-new-undefined-constant-glob-brace-while-doc-base-configure-php https://github.com/zendframework/zend-stdlib/issues/58
Sorry, it seems this situation has already been handled. Thank you. https://github.com/symfony/symfony/pull/21289/files#diff-ad1ed76aba6a80df5a48dfa4585adcf3R115