Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3c9a591

Browse files
committed
feature #22903 [DI] Deprecate XML services without ID (ro0NL)
This PR was merged into the 3.4 branch. Discussion ---------- [DI] Deprecate XML services without ID | Q | A | ------------- | --- | Branch? | 3.4 | Bug fix? | no, confusing though | New feature? | yes | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | #... <!-- #-prefixed issue number(s), if any --> | License | MIT | Doc PR | symfony/symfony-docs#... <!--highly recommended for new features--> On slack someone had a issue with class named services; > So, probably should have done this sooner, I stepped through with a debugger and it looks like \Symfony\Component\DependencyInjection\Loader\XmlFileLoader::processAnonymousServices assigns a sha256 to services that don't have any IDs > When my manually wired service is registered, it has an ID that looks like 1_344b468f6069ffe8c32092409d99c59abc218f41071ce4c4230c198876129bc0, so it doesn't override the auto-loaded one > I swear I read that IDs default to the class name now... The fix was easy; doing `<service id="ClassName"/>` instead of `<service class="ClassName"/>`. However the thing is... i made the exact same mistake trying to reproduce 😅 I think given the recent developments (dropping type based autowiring and class named services) it makes sense to force XML service to specify an ID attribute (the top level ones). This would be consistent with YAML and PHP as well. Fixing deprecations is also easy, just change `class` attribute to `id` like i've done for the frameworkbundle in this PR. Any thoughts? Commits ------- b8c68da [DI] Deprecate XML services without ID
2 parents f34a255 + b8c68da commit 3c9a591

File tree

10 files changed

+61
-9
lines changed

10 files changed

+61
-9
lines changed

UPGRADE-3.4.md

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
UPGRADE FROM 3.3 to 3.4
22
=======================
33

4+
DependencyInjection
5+
-------------------
6+
7+
* Top-level anonymous services in XML are deprecated and will throw an exception in Symfony 4.0.
8+
49
Finder
510
------
611

712
* The `Symfony\Component\Finder\Iterator\FilterIterator` class has been
813
deprecated and will be removed in 4.0 as it used to fix a bug which existed
9-
before version 5.5.23/5.6.7
14+
before version 5.5.23/5.6.7.
1015

1116
Validator
1217
---------
1318

14-
* not setting the `strict` option of the `Choice` constraint to `true` is
15-
deprecated and will throw an exception in Symfony 4.0
19+
* Not setting the `strict` option of the `Choice` constraint to `true` is
20+
deprecated and will throw an exception in Symfony 4.0.

UPGRADE-4.0.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,8 @@ DependencyInjection
128128
* The ``strict`` attribute in service arguments has been removed.
129129
The attribute is ignored since 3.0, so you can simply remove it.
130130

131+
* Top-level anonymous services in XML are no longer supported.
132+
131133
EventDispatcher
132134
---------------
133135

src/Symfony/Bundle/FrameworkBundle/Resources/config/services.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,12 @@
6666
<argument /> <!-- resource checkers -->
6767
</service>
6868

69-
<service class="Symfony\Component\DependencyInjection\Config\ContainerParametersResourceChecker">
69+
<service id="Symfony\Component\DependencyInjection\Config\ContainerParametersResourceChecker">
7070
<argument type="service" id="service_container" />
7171
<tag name="config_cache.resource_checker" priority="-980" />
7272
</service>
7373

74-
<service class="Symfony\Component\Config\Resource\SelfCheckingResourceChecker">
74+
<service id="Symfony\Component\Config\Resource\SelfCheckingResourceChecker">
7575
<tag name="config_cache.resource_checker" priority="-990" />
7676
</service>
7777
</services>

src/Symfony/Component/DependencyInjection/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
-----
66

77
* deprecated the ability to check for the initialization of a private service with the `Container::initialized()` method
8+
* deprecated support for top-level anonymous services in XML
89

910
3.3.0
1011
-----

src/Symfony/Component/DependencyInjection/Loader/XmlFileLoader.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,8 @@ private function processAnonymousServices(\DOMDocument $xml, $file, $defaults)
413413
// anonymous services "in the wild"
414414
if (false !== $nodes = $xpath->query('//container:services/container:service[not(@id)]')) {
415415
foreach ($nodes as $node) {
416+
@trigger_error(sprintf('Top-level anonymous services are deprecated since Symfony 3.4, the "id" attribute will be required in version 4.0 in %s at line %d.', $file, $node->getLineNo()), E_USER_DEPRECATED);
417+
416418
// give it a unique name
417419
$id = sprintf('%d_%s', ++$count, hash('sha256', $file));
418420
$node->setAttribute('id', $id);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
3+
<services>
4+
<service id="FooClass">
5+
<argument type="service">
6+
<service class="BarClass" />
7+
</argument>
8+
</service>
9+
</services>
10+
</container>

src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services28.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
<tag name="foo" />
66
</defaults>
77

8-
<service class="Bar" public="true" />
8+
<service id="bar" class="Bar" public="true" />
99
<service id="with_defaults" class="Foo" />
1010
<service id="no_defaults" class="Foo" public="true" autowire="false" />
1111
<service id="child_def" parent="with_defaults" public="true" autowire="false" />

src/Symfony/Component/DependencyInjection/Tests/Fixtures/xml/services5.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
</property>
1919
</service>
2020
<service id="bar" parent="foo" />
21-
<service class="BizClass">
21+
<service id="biz" class="BizClass">
2222
<tag name="biz_tag" />
2323
</service>
2424
</services>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
3+
<services>
4+
<service class="FooClass"/>
5+
<service id="FooClass">
6+
<argument type="service">
7+
<service class="BarClass" />
8+
</argument>
9+
</service>
10+
</services>
11+
</container>

src/Symfony/Component/DependencyInjection/Tests/Loader/XmlFileLoaderTest.php

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,28 @@ public function testLoadAnonymousServices()
230230
$this->assertSame($fooArgs[0], $barArgs[0]);
231231
}
232232

233+
/**
234+
* @group legacy
235+
* @expectedDeprecation Top-level anonymous services are deprecated since Symfony 3.4, the "id" attribute will be required in version 4.0 in %sservices_without_id.xml at line 4.
236+
*/
237+
public function testLoadAnonymousServicesWithoutId()
238+
{
239+
$container = new ContainerBuilder();
240+
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
241+
$loader->load('services_without_id.xml');
242+
}
243+
244+
public function testLoadAnonymousNestedServices()
245+
{
246+
$container = new ContainerBuilder();
247+
$loader = new XmlFileLoader($container, new FileLocator(self::$fixturesPath.'/xml'));
248+
$loader->load('nested_service_without_id.xml');
249+
250+
$this->assertTrue($container->hasDefinition('FooClass'));
251+
$arguments = $container->getDefinition('FooClass')->getArguments();
252+
$this->assertInstanceOf(Reference::class, array_shift($arguments));
253+
}
254+
233255
public function testLoadServices()
234256
{
235257
$container = new ContainerBuilder();
@@ -667,9 +689,8 @@ public function testDefaults()
667689
$this->assertSame('service_container', key($definitions));
668690

669691
array_shift($definitions);
670-
$this->assertStringStartsWith('1_', key($definitions));
671-
672692
$anonymous = current($definitions);
693+
$this->assertSame('bar', key($definitions));
673694
$this->assertTrue($anonymous->isPublic());
674695
$this->assertTrue($anonymous->isAutowired());
675696
$this->assertSame(array('foo' => array(array())), $anonymous->getTags());

0 commit comments

Comments
 (0)