Description
Q | A |
---|---|
Bug report? | yesish |
Feature request? | no |
BC Break report? | not really |
RFC? | no |
Symfony version | 3.3 |
Since #21133, the class
attribute isn't required anymore when using a classname as service id:
services:
Vendor\Namespace\Class: ~
However, due to the current implementation, the following is considered valid too:
services:
bar:
arguments: ['foo']
The bar
key is considered valid, and will be used as the Definition
class, despite there is no bar
class in the project.
Which means no compile-time exception. You'll only get:
Fatal error: Uncaught Symfony\Component\Debug\Exception\ClassNotFoundException: Attempted to load class "bar" from the global namespace.
Did you forget a "use" statement?
at runtime, when trying to use the service.
Previously, you got an error at compilation time:
Fatal error: Uncaught Symfony\Component\DependencyInjection\Exception\RuntimeException: The definition for "bar" has no class.
I think it's a DX regression, especially for someone not being aware of this behavior.
But the fact is that, looking at the tests, it seems expected.
In #20943 (comment), I suggested to enforce a leading backslash for global namespace classes, ie:
services:
\bar: ~
but that's not something to consider, given one of the main benefits of declaring a service this way, is to call it using $container->get(\bar::class)
. Which doesn't resolves to a FQCN with a leading backslash.
So, unless we move the service id as definition class logic inside each loaders, it's probably a no-go...
First question: Should we care?
Then, what are the possible solutions ?
- Enforce a leading backslash from file loaders but keeping the ability to do
which means moving the logic to yaml and xml file loaders. Which creates an inconsistent behavior between formats and probably gives wrong responsibilities to the loaders compared to the compiler pass.
$container->register(\ExistingClassFromTheGlobalNamespace::class)
- Do not accept classes from the global namespace, or at least only accept classes from the global namespace starting with an uppercase char.
In my experience, most services ids are lowercased (despite the fact case doesn't matter until [DI] Deprecate case insentivity of service identifiers #21193), whereas classnames are mainly capitalized (despite there is no recommendation about it in PSR-0/PSR-4 AFAIK), so it'll prevent WTF moments for a majority and looks sensible to me. - Anything else?