Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 99f285f

Browse filesBrowse files
[DI] Deprecate case insentivity of service identifiers
1 parent e66e6af commit 99f285f
Copy full SHA for 99f285f

File tree

21 files changed

+277
-98
lines changed
Filter options

21 files changed

+277
-98
lines changed

‎UPGRADE-3.3.md

Copy file name to clipboardExpand all lines: UPGRADE-3.3.md
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ ClassLoader
1010
DependencyInjection
1111
-------------------
1212

13+
* The `Reference` and `Alias` classes do not make service identifiers lowercase anymore.
14+
15+
* Case insensitivity of service identifiers is deprecated and will be removed in 4.0.
16+
1317
* Using the `PhpDumper` with an uncompiled `ContainerBuilder` is deprecated and
1418
will not be supported anymore in 4.0.
1519

‎src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolPass.php
+3-4Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ public function process(ContainerBuilder $container)
3636
}
3737
$seed .= '.'.$container->getParameter('kernel.name').'.'.$container->getParameter('kernel.environment');
3838

39-
$aliases = $container->getAliases();
4039
$attributes = array(
4140
'provider',
4241
'namespace',
@@ -59,9 +58,9 @@ public function process(ContainerBuilder $container)
5958
$tags[0]['namespace'] = $this->getNamespace($seed, $id);
6059
}
6160
if (isset($tags[0]['clearer'])) {
62-
$clearer = strtolower($tags[0]['clearer']);
63-
while (isset($aliases[$clearer])) {
64-
$clearer = (string) $aliases[$clearer];
61+
$clearer = $tags[0]['clearer'];
62+
while ($container->hasAlias($clearer)) {
63+
$clearer = (string) $container->getAlias($clearer);
6564
}
6665
} else {
6766
$clearer = null;

‎src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/FrameworkExtensionTest.php
+8-8Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -320,26 +320,26 @@ public function testAssets()
320320
$packages = $container->getDefinition('assets.packages');
321321

322322
// default package
323-
$defaultPackage = $container->getDefinition($packages->getArgument(0));
323+
$defaultPackage = $container->getDefinition((string) $packages->getArgument(0));
324324
$this->assertUrlPackage($container, $defaultPackage, array('http://cdn.example.com'), 'SomeVersionScheme', '%%s?version=%%s');
325325

326326
// packages
327327
$packages = $packages->getArgument(1);
328328
$this->assertCount(5, $packages);
329329

330-
$package = $container->getDefinition($packages['images_path']);
330+
$package = $container->getDefinition((string) $packages['images_path']);
331331
$this->assertPathPackage($container, $package, '/foo', 'SomeVersionScheme', '%%s?version=%%s');
332332

333-
$package = $container->getDefinition($packages['images']);
333+
$package = $container->getDefinition((string) $packages['images']);
334334
$this->assertUrlPackage($container, $package, array('http://images1.example.com', 'http://images2.example.com'), '1.0.0', '%%s?version=%%s');
335335

336-
$package = $container->getDefinition($packages['foo']);
336+
$package = $container->getDefinition((string) $packages['foo']);
337337
$this->assertPathPackage($container, $package, '', '1.0.0', '%%s-%%s');
338338

339-
$package = $container->getDefinition($packages['bar']);
339+
$package = $container->getDefinition((string) $packages['bar']);
340340
$this->assertUrlPackage($container, $package, array('https://bar2.example.com'), 'SomeVersionScheme', '%%s?version=%%s');
341341

342-
$package = $container->getDefinition($packages['bar_version_strategy']);
342+
$package = $container->getDefinition((string) $packages['bar_version_strategy']);
343343
$this->assertEquals('assets.custom_version_strategy', (string) $package->getArgument(1));
344344
}
345345

@@ -349,7 +349,7 @@ public function testAssetsDefaultVersionStrategyAsService()
349349
$packages = $container->getDefinition('assets.packages');
350350

351351
// default package
352-
$defaultPackage = $container->getDefinition($packages->getArgument(0));
352+
$defaultPackage = $container->getDefinition((string) $packages->getArgument(0));
353353
$this->assertEquals('assets.custom_version_strategy', (string) $defaultPackage->getArgument(1));
354354
}
355355

@@ -865,7 +865,7 @@ private function assertUrlPackage(ContainerBuilder $container, ChildDefinition $
865865

866866
private function assertVersionStrategy(ContainerBuilder $container, Reference $reference, $version, $format)
867867
{
868-
$versionStrategy = $container->getDefinition($reference);
868+
$versionStrategy = $container->getDefinition((string) $reference);
869869
if (null === $version) {
870870
$this->assertEquals('assets.empty_version_strategy', (string) $reference);
871871
} else {

‎src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,7 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
407407
$config->replaceArgument(8, isset($firewall['access_denied_handler']) ? $firewall['access_denied_handler'] : null);
408408
$config->replaceArgument(9, isset($firewall['access_denied_url']) ? $firewall['access_denied_url'] : null);
409409

410-
$container->setAlias(new Alias('security.user_checker.'.$id, false), $firewall['user_checker']);
410+
$container->setAlias('security.user_checker.'.$id, new Alias($firewall['user_checker'], false));
411411

412412
foreach ($this->factories as $position) {
413413
foreach ($position as $factory) {

‎src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/CompleteConfigurationTest.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ public function testFirewalls()
7373
$arguments = $contextDef->getArguments();
7474
$listeners[] = array_map(function ($ref) { return (string) $ref; }, $arguments['index_0']);
7575

76-
$configDef = $container->getDefinition($arguments['index_2']);
76+
$configDef = $container->getDefinition((string) $arguments['index_2']);
7777
$configs[] = array_values($configDef->getArguments());
7878
}
7979

@@ -234,7 +234,7 @@ public function testAccess()
234234
);
235235
} elseif (3 === $i) {
236236
$this->assertEquals('IS_AUTHENTICATED_ANONYMOUSLY', $attributes[0]);
237-
$expression = $container->getDefinition($attributes[1])->getArgument(0);
237+
$expression = $container->getDefinition((string) $attributes[1])->getArgument(0);
238238
$this->assertEquals("token.getUsername() matches '/^admin/'", $expression);
239239
}
240240
}

‎src/Symfony/Component/DependencyInjection/Alias.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Alias.php
+6-1Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,12 @@ class Alias
2222
*/
2323
public function __construct($id, $public = true)
2424
{
25-
$this->id = strtolower($id);
25+
if (!is_string($id)) {
26+
$type = is_object($id) ? get_class($id) : gettype($id);
27+
$id = (string) $id;
28+
@trigger_error(sprintf('Non-string identifiers are deprecated since Symfony 3.3 and won\'t be supported in 4.0 for Alias to "%s" ("%s" given.) Cast it to string beforehand.', $id, $type), E_USER_DEPRECATED);
29+
}
30+
$this->id = $id;
2631
$this->public = $public;
2732
}
2833

‎src/Symfony/Component/DependencyInjection/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/CHANGELOG.md
+3-1Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ CHANGELOG
44
3.3.0
55
-----
66

7+
* deprecated case insensitivity of service identifiers
78
* added "iterator" argument type for lazy iteration over a set of values and services
89
* added "closure-proxy" argument type for turning services' methods into lazy callables
910
* added file-wide configurable defaults for service attributes "public", "tags",
10-
"autowire" and a new "inherit-tags"
11+
"autowire" and "inherit-tags"
12+
* added "inherit-tags" service attribute to control tags' inheritance from parent context
1113
* made the "class" attribute optional, using the "id" as fallback
1214
* using the `PhpDumper` with an uncompiled `ContainerBuilder` is deprecated and
1315
will not be supported anymore in 4.0

‎src/Symfony/Component/DependencyInjection/Compiler/FactoryReturnTypePass.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/FactoryReturnTypePass.php
+6-5Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,13 @@ public function process(ContainerBuilder $container)
5151
private function updateDefinition(ContainerBuilder $container, $id, Definition $definition, array $resolveClassPassChanges, array $previous = array())
5252
{
5353
// circular reference
54-
if (isset($previous[$id])) {
54+
$lcId = strtolower($id);
55+
if (isset($previous[$lcId])) {
5556
return;
5657
}
5758

5859
$factory = $definition->getFactory();
59-
if (null === $factory || (!isset($resolveClassPassChanges[$id]) && null !== $definition->getClass())) {
60+
if (null === $factory || (!isset($resolveClassPassChanges[$lcId]) && null !== $definition->getClass())) {
6061
return;
6162
}
6263

@@ -69,9 +70,9 @@ private function updateDefinition(ContainerBuilder $container, $id, Definition $
6970
}
7071
} else {
7172
if ($factory[0] instanceof Reference) {
72-
$previous[$id] = true;
73+
$previous[$lcId] = true;
7374
$factoryDefinition = $container->findDefinition((string) $factory[0]);
74-
$this->updateDefinition($container, strtolower($factory[0]), $factoryDefinition, $resolveClassPassChanges, $previous);
75+
$this->updateDefinition($container, $factory[0], $factoryDefinition, $resolveClassPassChanges, $previous);
7576
$class = $factoryDefinition->getClass();
7677
} else {
7778
$class = $factory[0];
@@ -96,7 +97,7 @@ private function updateDefinition(ContainerBuilder $container, $id, Definition $
9697
}
9798
}
9899

99-
if (null !== $returnType && (!isset($resolveClassPassChanges[$id]) || $returnType !== $resolveClassPassChanges[$id])) {
100+
if (null !== $returnType && (!isset($resolveClassPassChanges[$lcId]) || $returnType !== $resolveClassPassChanges[$lcId])) {
100101
@trigger_error(sprintf('Relying on its factory\'s return-type to define the class of service "%s" is deprecated since Symfony 3.3 and won\'t work in 4.0. Set the "class" attribute to "%s" on the service definition instead.', $id, $returnType), E_USER_DEPRECATED);
101102
}
102103
$definition->setClass($returnType);

‎src/Symfony/Component/DependencyInjection/Compiler/ResolveClassPass.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Compiler/ResolveClassPass.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ public function process(ContainerBuilder $container)
3131
continue;
3232
}
3333
if (preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+$/', $id)) {
34-
$this->changes[$id] = $container->getCaseSensitiveId($id);
35-
$definition->setClass($this->changes[$id]);
34+
$this->changes[strtolower($id)] = $id;
35+
$definition->setClass($id);
3636
}
3737
}
3838
}

‎src/Symfony/Component/DependencyInjection/Container.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/DependencyInjection/Container.php
+41-7Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,11 @@ class Container implements ResettableContainerInterface
7070
protected $aliases = array();
7171
protected $loading = array();
7272

73+
/**
74+
* @internal
75+
*/
76+
protected $normalizedIds = array();
77+
7378
private $underscoreMap = array('_' => '', '.' => '_', '\\' => '_');
7479
private $envCache = array();
7580

@@ -164,7 +169,7 @@ public function setParameter($name, $value)
164169
*/
165170
public function set($id, $service)
166171
{
167-
$id = strtolower($id);
172+
$id = $this->normalizeId($id);
168173

169174
if ('service_container' === $id) {
170175
throw new InvalidArgumentException('You cannot set service "service_container".');
@@ -215,8 +220,8 @@ public function has($id)
215220
return true;
216221
}
217222

218-
if (--$i && $id !== $lcId = strtolower($id)) {
219-
$id = $lcId;
223+
if (--$i && $id !== $normalizedId = $this->normalizeId($id)) {
224+
$id = $normalizedId;
220225
continue;
221226
}
222227

@@ -254,7 +259,7 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE
254259
// Attempt to retrieve the service by checking first aliases then
255260
// available services. Service IDs are case insensitive, however since
256261
// this method can be called thousands of times during a request, avoid
257-
// calling strtolower() unless necessary.
262+
// calling $this->normalizeId($id) unless necessary.
258263
for ($i = 2;;) {
259264
if ('service_container' === $id) {
260265
return $this;
@@ -273,8 +278,8 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE
273278

274279
if (isset($this->methodMap[$id])) {
275280
$method = $this->methodMap[$id];
276-
} elseif (--$i && $id !== $lcId = strtolower($id)) {
277-
$id = $lcId;
281+
} elseif (--$i && $id !== $normalizedId = $this->normalizeId($id)) {
282+
$id = $normalizedId;
278283
continue;
279284
} elseif (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class && method_exists($this, $method = 'get'.strtr($id, $this->underscoreMap).'Service')) {
280285
// We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder,
@@ -329,7 +334,7 @@ public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE
329334
*/
330335
public function initialized($id)
331336
{
332-
$id = strtolower($id);
337+
$id = $this->normalizeId($id);
333338

334339
if ('service_container' === $id) {
335340
return false;
@@ -426,6 +431,35 @@ protected function getEnv($name)
426431
return $this->envCache[$name] = $this->getParameter("env($name)");
427432
}
428433

434+
/**
435+
* Returns the case sensitive id used at registration time.
436+
*
437+
* @param string $id
438+
* @param bool $forUpdate
439+
*
440+
* @return string
441+
*
442+
* @internal
443+
*/
444+
public function normalizeId($id)
445+
{
446+
if (!is_string($id)) {
447+
$type = is_object($id) ? get_class($id) : gettype($id);
448+
$id = (string) $id;
449+
@trigger_error(sprintf('Non-string service identifiers are deprecated since Symfony 3.3 and won\'t be supported in 4.0 for service "%s" ("%s" given.) Cast it to string beforehand.', $id, $type), E_USER_DEPRECATED);
450+
}
451+
if (isset($this->normalizedIds[$normalizedId = strtolower($id)])) {
452+
$normalizedId = $this->normalizedIds[$normalizedId];
453+
if ($id !== $normalizedId) {
454+
@trigger_error(sprintf('Service identifiers will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since version 3.3.', $id, $normalizedId), E_USER_DEPRECATED);
455+
}
456+
} else {
457+
$normalizedId = $this->normalizedIds[$normalizedId] = $id;
458+
}
459+
460+
return $normalizedId;
461+
}
462+
429463
private function __clone()
430464
{
431465
}

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.