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

Skip to content

Commit 7aeb31e

Browse files
committed
feature #21223 [DI] Deprecate case insentivity of service identifiers (nicolas-grekas)
This PR was merged into the 3.3-dev branch. Discussion ---------- [DI] Deprecate case insentivity of service identifiers | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | minor (see UPGRADE note) | Deprecations? | yes | Tests pass? | yes | Fixed tickets | #21193 | License | MIT | Doc PR | - As discussed in linked RFC. Commits ------- d08f110 [DI] Deprecate case insentivity of service identifiers
2 parents df876b3 + d08f110 commit 7aeb31e

17 files changed

+258
-73
lines changed

UPGRADE-3.3.md

Lines 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

UPGRADE-4.0.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ Debug
2222
DependencyInjection
2323
-------------------
2424

25+
* Service identifiers are now case sensitive.
26+
27+
* The `Reference` and `Alias` classes do not make service identifiers lowercase anymore.
28+
2529
* Using the `PhpDumper` with an uncompiled `ContainerBuilder` is not supported
2630
anymore.
2731

src/Symfony/Component/DependencyInjection/Alias.php

Lines 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

Lines 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

Lines 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

Lines 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

Lines changed: 40 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,34 @@ 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+
*
439+
* @return string
440+
*
441+
* @internal
442+
*/
443+
public function normalizeId($id)
444+
{
445+
if (!is_string($id)) {
446+
$type = is_object($id) ? get_class($id) : gettype($id);
447+
$id = (string) $id;
448+
@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);
449+
}
450+
if (isset($this->normalizedIds[$normalizedId = strtolower($id)])) {
451+
$normalizedId = $this->normalizedIds[$normalizedId];
452+
if ($id !== $normalizedId) {
453+
@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);
454+
}
455+
} else {
456+
$normalizedId = $this->normalizedIds[$normalizedId] = $id;
457+
}
458+
459+
return $normalizedId;
460+
}
461+
429462
private function __clone()
430463
{
431464
}

0 commit comments

Comments
 (0)