[DI] Deprecate case insentivity of service identifiers
This commit is contained in:
parent
16d33e1fff
commit
d08f1101df
@ -10,6 +10,10 @@ ClassLoader
|
|||||||
DependencyInjection
|
DependencyInjection
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
* The `Reference` and `Alias` classes do not make service identifiers lowercase anymore.
|
||||||
|
|
||||||
|
* Case insensitivity of service identifiers is deprecated and will be removed in 4.0.
|
||||||
|
|
||||||
* Using the `PhpDumper` with an uncompiled `ContainerBuilder` is deprecated and
|
* Using the `PhpDumper` with an uncompiled `ContainerBuilder` is deprecated and
|
||||||
will not be supported anymore in 4.0.
|
will not be supported anymore in 4.0.
|
||||||
|
|
||||||
|
@ -22,6 +22,10 @@ Debug
|
|||||||
DependencyInjection
|
DependencyInjection
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
* Service identifiers are now case sensitive.
|
||||||
|
|
||||||
|
* The `Reference` and `Alias` classes do not make service identifiers lowercase anymore.
|
||||||
|
|
||||||
* Using the `PhpDumper` with an uncompiled `ContainerBuilder` is not supported
|
* Using the `PhpDumper` with an uncompiled `ContainerBuilder` is not supported
|
||||||
anymore.
|
anymore.
|
||||||
|
|
||||||
|
@ -22,7 +22,12 @@ class Alias
|
|||||||
*/
|
*/
|
||||||
public function __construct($id, $public = true)
|
public function __construct($id, $public = true)
|
||||||
{
|
{
|
||||||
$this->id = strtolower($id);
|
if (!is_string($id)) {
|
||||||
|
$type = is_object($id) ? get_class($id) : gettype($id);
|
||||||
|
$id = (string) $id;
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
$this->id = $id;
|
||||||
$this->public = $public;
|
$this->public = $public;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,10 +4,12 @@ CHANGELOG
|
|||||||
3.3.0
|
3.3.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
* deprecated case insensitivity of service identifiers
|
||||||
* added "iterator" argument type for lazy iteration over a set of values and services
|
* added "iterator" argument type for lazy iteration over a set of values and services
|
||||||
* added "closure-proxy" argument type for turning services' methods into lazy callables
|
* added "closure-proxy" argument type for turning services' methods into lazy callables
|
||||||
* added file-wide configurable defaults for service attributes "public", "tags",
|
* added file-wide configurable defaults for service attributes "public", "tags",
|
||||||
"autowire" and a new "inherit-tags"
|
"autowire" and "inherit-tags"
|
||||||
|
* added "inherit-tags" service attribute to control tags' inheritance from parent context
|
||||||
* made the "class" attribute optional, using the "id" as fallback
|
* made the "class" attribute optional, using the "id" as fallback
|
||||||
* using the `PhpDumper` with an uncompiled `ContainerBuilder` is deprecated and
|
* using the `PhpDumper` with an uncompiled `ContainerBuilder` is deprecated and
|
||||||
will not be supported anymore in 4.0
|
will not be supported anymore in 4.0
|
||||||
|
@ -51,12 +51,13 @@ class FactoryReturnTypePass implements CompilerPassInterface
|
|||||||
private function updateDefinition(ContainerBuilder $container, $id, Definition $definition, array $resolveClassPassChanges, array $previous = array())
|
private function updateDefinition(ContainerBuilder $container, $id, Definition $definition, array $resolveClassPassChanges, array $previous = array())
|
||||||
{
|
{
|
||||||
// circular reference
|
// circular reference
|
||||||
if (isset($previous[$id])) {
|
$lcId = strtolower($id);
|
||||||
|
if (isset($previous[$lcId])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$factory = $definition->getFactory();
|
$factory = $definition->getFactory();
|
||||||
if (null === $factory || (!isset($resolveClassPassChanges[$id]) && null !== $definition->getClass())) {
|
if (null === $factory || (!isset($resolveClassPassChanges[$lcId]) && null !== $definition->getClass())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,9 +70,9 @@ class FactoryReturnTypePass implements CompilerPassInterface
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ($factory[0] instanceof Reference) {
|
if ($factory[0] instanceof Reference) {
|
||||||
$previous[$id] = true;
|
$previous[$lcId] = true;
|
||||||
$factoryDefinition = $container->findDefinition((string) $factory[0]);
|
$factoryDefinition = $container->findDefinition((string) $factory[0]);
|
||||||
$this->updateDefinition($container, strtolower($factory[0]), $factoryDefinition, $resolveClassPassChanges, $previous);
|
$this->updateDefinition($container, $factory[0], $factoryDefinition, $resolveClassPassChanges, $previous);
|
||||||
$class = $factoryDefinition->getClass();
|
$class = $factoryDefinition->getClass();
|
||||||
} else {
|
} else {
|
||||||
$class = $factory[0];
|
$class = $factory[0];
|
||||||
@ -96,7 +97,7 @@ class FactoryReturnTypePass implements CompilerPassInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (null !== $returnType && (!isset($resolveClassPassChanges[$id]) || $returnType !== $resolveClassPassChanges[$id])) {
|
if (null !== $returnType && (!isset($resolveClassPassChanges[$lcId]) || $returnType !== $resolveClassPassChanges[$lcId])) {
|
||||||
@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);
|
@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);
|
||||||
}
|
}
|
||||||
$definition->setClass($returnType);
|
$definition->setClass($returnType);
|
||||||
|
@ -31,8 +31,8 @@ class ResolveClassPass implements CompilerPassInterface
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
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)) {
|
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)) {
|
||||||
$this->changes[$id] = $container->getCaseSensitiveId($id);
|
$this->changes[strtolower($id)] = $id;
|
||||||
$definition->setClass($this->changes[$id]);
|
$definition->setClass($id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,6 +70,11 @@ class Container implements ResettableContainerInterface
|
|||||||
protected $aliases = array();
|
protected $aliases = array();
|
||||||
protected $loading = array();
|
protected $loading = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
protected $normalizedIds = array();
|
||||||
|
|
||||||
private $underscoreMap = array('_' => '', '.' => '_', '\\' => '_');
|
private $underscoreMap = array('_' => '', '.' => '_', '\\' => '_');
|
||||||
private $envCache = array();
|
private $envCache = array();
|
||||||
|
|
||||||
@ -164,7 +169,7 @@ class Container implements ResettableContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function set($id, $service)
|
public function set($id, $service)
|
||||||
{
|
{
|
||||||
$id = strtolower($id);
|
$id = $this->normalizeId($id);
|
||||||
|
|
||||||
if ('service_container' === $id) {
|
if ('service_container' === $id) {
|
||||||
throw new InvalidArgumentException('You cannot set service "service_container".');
|
throw new InvalidArgumentException('You cannot set service "service_container".');
|
||||||
@ -215,8 +220,8 @@ class Container implements ResettableContainerInterface
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (--$i && $id !== $lcId = strtolower($id)) {
|
if (--$i && $id !== $normalizedId = $this->normalizeId($id)) {
|
||||||
$id = $lcId;
|
$id = $normalizedId;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -254,7 +259,7 @@ class Container implements ResettableContainerInterface
|
|||||||
// Attempt to retrieve the service by checking first aliases then
|
// Attempt to retrieve the service by checking first aliases then
|
||||||
// available services. Service IDs are case insensitive, however since
|
// available services. Service IDs are case insensitive, however since
|
||||||
// this method can be called thousands of times during a request, avoid
|
// this method can be called thousands of times during a request, avoid
|
||||||
// calling strtolower() unless necessary.
|
// calling $this->normalizeId($id) unless necessary.
|
||||||
for ($i = 2;;) {
|
for ($i = 2;;) {
|
||||||
if ('service_container' === $id) {
|
if ('service_container' === $id) {
|
||||||
return $this;
|
return $this;
|
||||||
@ -273,8 +278,8 @@ class Container implements ResettableContainerInterface
|
|||||||
|
|
||||||
if (isset($this->methodMap[$id])) {
|
if (isset($this->methodMap[$id])) {
|
||||||
$method = $this->methodMap[$id];
|
$method = $this->methodMap[$id];
|
||||||
} elseif (--$i && $id !== $lcId = strtolower($id)) {
|
} elseif (--$i && $id !== $normalizedId = $this->normalizeId($id)) {
|
||||||
$id = $lcId;
|
$id = $normalizedId;
|
||||||
continue;
|
continue;
|
||||||
} elseif (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class && method_exists($this, $method = 'get'.strtr($id, $this->underscoreMap).'Service')) {
|
} elseif (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class && method_exists($this, $method = 'get'.strtr($id, $this->underscoreMap).'Service')) {
|
||||||
// We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder,
|
// We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder,
|
||||||
@ -329,7 +334,7 @@ class Container implements ResettableContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function initialized($id)
|
public function initialized($id)
|
||||||
{
|
{
|
||||||
$id = strtolower($id);
|
$id = $this->normalizeId($id);
|
||||||
|
|
||||||
if ('service_container' === $id) {
|
if ('service_container' === $id) {
|
||||||
return false;
|
return false;
|
||||||
@ -426,6 +431,34 @@ class Container implements ResettableContainerInterface
|
|||||||
return $this->envCache[$name] = $this->getParameter("env($name)");
|
return $this->envCache[$name] = $this->getParameter("env($name)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the case sensitive id used at registration time.
|
||||||
|
*
|
||||||
|
* @param string $id
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public function normalizeId($id)
|
||||||
|
{
|
||||||
|
if (!is_string($id)) {
|
||||||
|
$type = is_object($id) ? get_class($id) : gettype($id);
|
||||||
|
$id = (string) $id;
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
if (isset($this->normalizedIds[$normalizedId = strtolower($id)])) {
|
||||||
|
$normalizedId = $this->normalizedIds[$normalizedId];
|
||||||
|
if ($id !== $normalizedId) {
|
||||||
|
@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);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$normalizedId = $this->normalizedIds[$normalizedId] = $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $normalizedId;
|
||||||
|
}
|
||||||
|
|
||||||
private function __clone()
|
private function __clone()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -103,11 +103,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
private $envCounters = array();
|
private $envCounters = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array a map of case less to case sensitive ids
|
|
||||||
*/
|
|
||||||
private $caseSensitiveIds = array();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the track resources flag.
|
* Sets the track resources flag.
|
||||||
*
|
*
|
||||||
@ -372,8 +367,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function set($id, $service)
|
public function set($id, $service)
|
||||||
{
|
{
|
||||||
$caseSensitiveId = $id;
|
$id = $this->normalizeId($id);
|
||||||
$id = strtolower($caseSensitiveId);
|
|
||||||
|
|
||||||
if ($this->isFrozen() && (isset($this->definitions[$id]) && !$this->definitions[$id]->isSynthetic())) {
|
if ($this->isFrozen() && (isset($this->definitions[$id]) && !$this->definitions[$id]->isSynthetic())) {
|
||||||
// setting a synthetic service on a frozen container is alright
|
// setting a synthetic service on a frozen container is alright
|
||||||
@ -381,9 +375,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
unset($this->definitions[$id], $this->aliasDefinitions[$id]);
|
unset($this->definitions[$id], $this->aliasDefinitions[$id]);
|
||||||
if ($id !== $caseSensitiveId) {
|
|
||||||
$this->caseSensitiveIds[$id] = $caseSensitiveId;
|
|
||||||
}
|
|
||||||
|
|
||||||
parent::set($id, $service);
|
parent::set($id, $service);
|
||||||
}
|
}
|
||||||
@ -395,7 +386,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function removeDefinition($id)
|
public function removeDefinition($id)
|
||||||
{
|
{
|
||||||
unset($this->definitions[strtolower($id)]);
|
unset($this->definitions[$this->normalizeId($id)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -407,7 +398,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function has($id)
|
public function has($id)
|
||||||
{
|
{
|
||||||
$id = strtolower($id);
|
$id = $this->normalizeId($id);
|
||||||
|
|
||||||
return isset($this->definitions[$id]) || isset($this->aliasDefinitions[$id]) || parent::has($id);
|
return isset($this->definitions[$id]) || isset($this->aliasDefinitions[$id]) || parent::has($id);
|
||||||
}
|
}
|
||||||
@ -429,7 +420,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
|
public function get($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
|
||||||
{
|
{
|
||||||
$id = strtolower($id);
|
$id = $this->normalizeId($id);
|
||||||
|
|
||||||
if ($service = parent::get($id, ContainerInterface::NULL_ON_INVALID_REFERENCE)) {
|
if ($service = parent::get($id, ContainerInterface::NULL_ON_INVALID_REFERENCE)) {
|
||||||
return $service;
|
return $service;
|
||||||
@ -637,11 +628,10 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function setAlias($alias, $id)
|
public function setAlias($alias, $id)
|
||||||
{
|
{
|
||||||
$caseSensitiveAlias = $alias;
|
$alias = $this->normalizeId($alias);
|
||||||
$alias = strtolower($caseSensitiveAlias);
|
|
||||||
|
|
||||||
if (is_string($id)) {
|
if (is_string($id)) {
|
||||||
$id = new Alias($id);
|
$id = new Alias($this->normalizeId($id));
|
||||||
} elseif (!$id instanceof Alias) {
|
} elseif (!$id instanceof Alias) {
|
||||||
throw new InvalidArgumentException('$id must be a string, or an Alias object.');
|
throw new InvalidArgumentException('$id must be a string, or an Alias object.');
|
||||||
}
|
}
|
||||||
@ -651,9 +641,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
unset($this->definitions[$alias]);
|
unset($this->definitions[$alias]);
|
||||||
if ($alias !== $caseSensitiveAlias) {
|
|
||||||
$this->caseSensitiveIds[$alias] = $caseSensitiveAlias;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->aliasDefinitions[$alias] = $id;
|
$this->aliasDefinitions[$alias] = $id;
|
||||||
}
|
}
|
||||||
@ -665,7 +652,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function removeAlias($alias)
|
public function removeAlias($alias)
|
||||||
{
|
{
|
||||||
unset($this->aliasDefinitions[strtolower($alias)]);
|
unset($this->aliasDefinitions[$this->normalizeId($alias)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -677,7 +664,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function hasAlias($id)
|
public function hasAlias($id)
|
||||||
{
|
{
|
||||||
return isset($this->aliasDefinitions[strtolower($id)]);
|
return isset($this->aliasDefinitions[$this->normalizeId($id)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -701,7 +688,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function getAlias($id)
|
public function getAlias($id)
|
||||||
{
|
{
|
||||||
$id = strtolower($id);
|
$id = $this->normalizeId($id);
|
||||||
|
|
||||||
if (!isset($this->aliasDefinitions[$id])) {
|
if (!isset($this->aliasDefinitions[$id])) {
|
||||||
throw new InvalidArgumentException(sprintf('The service alias "%s" does not exist.', $id));
|
throw new InvalidArgumentException(sprintf('The service alias "%s" does not exist.', $id));
|
||||||
@ -791,13 +778,9 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
throw new BadMethodCallException('Adding definition to a frozen container is not allowed');
|
throw new BadMethodCallException('Adding definition to a frozen container is not allowed');
|
||||||
}
|
}
|
||||||
|
|
||||||
$caseSensitiveId = $id;
|
$id = $this->normalizeId($id);
|
||||||
$id = strtolower($caseSensitiveId);
|
|
||||||
|
|
||||||
unset($this->aliasDefinitions[$id]);
|
unset($this->aliasDefinitions[$id]);
|
||||||
if ($id !== $caseSensitiveId) {
|
|
||||||
$this->caseSensitiveIds[$id] = $caseSensitiveId;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->definitions[$id] = $definition;
|
return $this->definitions[$id] = $definition;
|
||||||
}
|
}
|
||||||
@ -811,7 +794,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function hasDefinition($id)
|
public function hasDefinition($id)
|
||||||
{
|
{
|
||||||
return isset($this->definitions[strtolower($id)]);
|
return isset($this->definitions[$this->normalizeId($id)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -825,7 +808,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function getDefinition($id)
|
public function getDefinition($id)
|
||||||
{
|
{
|
||||||
$id = strtolower($id);
|
$id = $this->normalizeId($id);
|
||||||
|
|
||||||
if (!isset($this->definitions[$id])) {
|
if (!isset($this->definitions[$id])) {
|
||||||
throw new ServiceNotFoundException($id);
|
throw new ServiceNotFoundException($id);
|
||||||
@ -847,7 +830,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
*/
|
*/
|
||||||
public function findDefinition($id)
|
public function findDefinition($id)
|
||||||
{
|
{
|
||||||
$id = strtolower($id);
|
$id = $this->normalizeId($id);
|
||||||
|
|
||||||
while (isset($this->aliasDefinitions[$id])) {
|
while (isset($this->aliasDefinitions[$id])) {
|
||||||
$id = (string) $this->aliasDefinitions[$id];
|
$id = (string) $this->aliasDefinitions[$id];
|
||||||
@ -856,22 +839,6 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
return $this->getDefinition($id);
|
return $this->getDefinition($id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the case sensitive id used at registration time.
|
|
||||||
*
|
|
||||||
* @param string $id
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
public function getCaseSensitiveId($id)
|
|
||||||
{
|
|
||||||
$id = strtolower($id);
|
|
||||||
|
|
||||||
return isset($this->caseSensitiveIds[$id]) ? $this->caseSensitiveIds[$id] : $id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a service for a service definition.
|
* Creates a service for a service definition.
|
||||||
*
|
*
|
||||||
@ -1188,6 +1155,22 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
return $this->envCounters;
|
return $this->envCounters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
public function getNormalizedIds()
|
||||||
|
{
|
||||||
|
$normalizedIds = array();
|
||||||
|
|
||||||
|
foreach ($this->normalizedIds as $k => $v) {
|
||||||
|
if ($v !== (string) $k) {
|
||||||
|
$normalizedIds[$k] = $v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $normalizedIds;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Service Conditionals.
|
* Returns the Service Conditionals.
|
||||||
*
|
*
|
||||||
@ -1247,7 +1230,7 @@ class ContainerBuilder extends Container implements TaggedContainerInterface
|
|||||||
private function shareService(Definition $definition, $service, $id)
|
private function shareService(Definition $definition, $service, $id)
|
||||||
{
|
{
|
||||||
if (null !== $id && $definition->isShared()) {
|
if (null !== $id && $definition->isShared()) {
|
||||||
$this->services[strtolower($id)] = $service;
|
$this->services[$this->normalizeId($id)] = $service;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,6 +835,7 @@ EOF;
|
|||||||
|
|
||||||
EOF;
|
EOF;
|
||||||
|
|
||||||
|
$code .= $this->addNormalizedIds();
|
||||||
$code .= $this->addMethodMap();
|
$code .= $this->addMethodMap();
|
||||||
$code .= $this->addPrivateServices();
|
$code .= $this->addPrivateServices();
|
||||||
$code .= $this->addAliases();
|
$code .= $this->addAliases();
|
||||||
@ -870,6 +871,7 @@ EOF;
|
|||||||
}
|
}
|
||||||
|
|
||||||
$code .= "\n \$this->services = array();\n";
|
$code .= "\n \$this->services = array();\n";
|
||||||
|
$code .= $this->addNormalizedIds();
|
||||||
$code .= $this->addMethodMap();
|
$code .= $this->addMethodMap();
|
||||||
$code .= $this->addAliases();
|
$code .= $this->addAliases();
|
||||||
|
|
||||||
@ -921,6 +923,26 @@ EOF;
|
|||||||
EOF;
|
EOF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the normalizedIds property definition.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function addNormalizedIds()
|
||||||
|
{
|
||||||
|
if (!$normalizedIds = $this->container->getNormalizedIds()) {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
|
||||||
|
$code = " \$this->normalizedIds = array(\n";
|
||||||
|
ksort($normalizedIds);
|
||||||
|
foreach ($normalizedIds as $id => $normalizedId) {
|
||||||
|
$code .= ' '.$this->export($id).' => '.$this->export($normalizedId).",\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $code." );\n";
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds the methodMap property definition.
|
* Adds the methodMap property definition.
|
||||||
*
|
*
|
||||||
|
@ -29,7 +29,12 @@ class Reference
|
|||||||
*/
|
*/
|
||||||
public function __construct($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
|
public function __construct($id, $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE)
|
||||||
{
|
{
|
||||||
$this->id = strtolower($id);
|
if (!is_string($id)) {
|
||||||
|
$type = is_object($id) ? get_class($id) : gettype($id);
|
||||||
|
$id = (string) $id;
|
||||||
|
@trigger_error(sprintf('Non-string identifiers are deprecated since Symfony 3.3 and won\'t be supported in 4.0 for Reference to "%s" ("%s" given.) Cast it to string beforehand.', $id, $type), E_USER_DEPRECATED);
|
||||||
|
}
|
||||||
|
$this->id = $id;
|
||||||
$this->invalidBehavior = $invalidBehavior;
|
$this->invalidBehavior = $invalidBehavior;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,13 +211,13 @@ class AutowirePassTest extends \PHPUnit_Framework_TestCase
|
|||||||
$pass->process($container);
|
$pass->process($container);
|
||||||
|
|
||||||
$this->assertCount(1, $container->getDefinition('coop_tilleuls')->getArguments());
|
$this->assertCount(1, $container->getDefinition('coop_tilleuls')->getArguments());
|
||||||
$this->assertEquals('autowired.symfony\component\dependencyinjection\tests\compiler\dunglas', $container->getDefinition('coop_tilleuls')->getArgument(0));
|
$this->assertEquals('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas', $container->getDefinition('coop_tilleuls')->getArgument(0));
|
||||||
|
|
||||||
$dunglasDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas');
|
$dunglasDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Dunglas');
|
||||||
$this->assertEquals(__NAMESPACE__.'\Dunglas', $dunglasDefinition->getClass());
|
$this->assertEquals(__NAMESPACE__.'\Dunglas', $dunglasDefinition->getClass());
|
||||||
$this->assertFalse($dunglasDefinition->isPublic());
|
$this->assertFalse($dunglasDefinition->isPublic());
|
||||||
$this->assertCount(1, $dunglasDefinition->getArguments());
|
$this->assertCount(1, $dunglasDefinition->getArguments());
|
||||||
$this->assertEquals('autowired.symfony\component\dependencyinjection\tests\compiler\lille', $dunglasDefinition->getArgument(0));
|
$this->assertEquals('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Lille', $dunglasDefinition->getArgument(0));
|
||||||
|
|
||||||
$lilleDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Lille');
|
$lilleDefinition = $container->getDefinition('autowired.Symfony\Component\DependencyInjection\Tests\Compiler\Lille');
|
||||||
$this->assertEquals(__NAMESPACE__.'\Lille', $lilleDefinition->getClass());
|
$this->assertEquals(__NAMESPACE__.'\Lille', $lilleDefinition->getClass());
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\DependencyInjection\Tests;
|
namespace Symfony\Component\DependencyInjection\Tests;
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\Alias;
|
||||||
use Symfony\Component\DependencyInjection\Container;
|
use Symfony\Component\DependencyInjection\Container;
|
||||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||||
@ -167,7 +168,6 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$sc = new ProjectServiceContainer();
|
$sc = new ProjectServiceContainer();
|
||||||
$sc->set('foo', $foo = new \stdClass());
|
$sc->set('foo', $foo = new \stdClass());
|
||||||
$this->assertSame($foo, $sc->get('foo'), '->get() returns the service for the given id');
|
$this->assertSame($foo, $sc->get('foo'), '->get() returns the service for the given id');
|
||||||
$this->assertSame($foo, $sc->get('Foo'), '->get() returns the service for the given id, and converts id to lowercase');
|
|
||||||
$this->assertSame($sc->__bar, $sc->get('bar'), '->get() returns the service for the given id');
|
$this->assertSame($sc->__bar, $sc->get('bar'), '->get() returns the service for the given id');
|
||||||
$this->assertSame($sc->__foo_bar, $sc->get('foo_bar'), '->get() returns the service if a get*Method() is defined');
|
$this->assertSame($sc->__foo_bar, $sc->get('foo_bar'), '->get() returns the service if a get*Method() is defined');
|
||||||
$this->assertSame($sc->__foo_baz, $sc->get('foo.baz'), '->get() returns the service if a get*Method() is defined');
|
$this->assertSame($sc->__foo_baz, $sc->get('foo.baz'), '->get() returns the service if a get*Method() is defined');
|
||||||
@ -184,6 +184,40 @@ class ContainerTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertNull($sc->get('', ContainerInterface::NULL_ON_INVALID_REFERENCE), '->get() returns null if the service is empty');
|
$this->assertNull($sc->get('', ContainerInterface::NULL_ON_INVALID_REFERENCE), '->get() returns null if the service is empty');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
* @expectedDeprecation Service identifiers will be made case sensitive in Symfony 4.0. Using "Foo" instead of "foo" is deprecated since version 3.3.
|
||||||
|
*/
|
||||||
|
public function testGetInsensitivity()
|
||||||
|
{
|
||||||
|
$sc = new ProjectServiceContainer();
|
||||||
|
$sc->set('foo', $foo = new \stdClass());
|
||||||
|
$this->assertSame($foo, $sc->get('Foo'), '->get() returns the service for the given id, and converts id to lowercase');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
* @expectedDeprecation Non-string service identifiers are deprecated since Symfony 3.3 and won't be supported in 4.0 for service "foo" ("Symfony\Component\DependencyInjection\Alias" given.) Cast it to string beforehand.
|
||||||
|
* @expectedDeprecation Service identifiers will be made case sensitive in Symfony 4.0. Using "Foo" instead of "foo" is deprecated since version 3.3.
|
||||||
|
*/
|
||||||
|
public function testNonStringNormalizeId()
|
||||||
|
{
|
||||||
|
$sc = new ProjectServiceContainer();
|
||||||
|
$this->assertSame('foo', $sc->normalizeId(new Alias('foo')));
|
||||||
|
$this->assertSame('foo', $sc->normalizeId('Foo'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
* @expectedDeprecation Service identifiers will be made case sensitive in Symfony 4.0. Using "foo" instead of "Foo" is deprecated since version 3.3.
|
||||||
|
*/
|
||||||
|
public function testNormalizeIdKeepsCase()
|
||||||
|
{
|
||||||
|
$sc = new ProjectServiceContainer();
|
||||||
|
$sc->normalizeId('Foo', true);
|
||||||
|
$this->assertSame('Foo', $sc->normalizeId('foo'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @group legacy
|
* @group legacy
|
||||||
* @expectedDeprecation Generating a dumped container without populating the method map is deprecated since 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.
|
* @expectedDeprecation Generating a dumped container without populating the method map is deprecated since 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.
|
||||||
|
@ -55,6 +55,11 @@ class CrossCheckTest extends \PHPUnit_Framework_TestCase
|
|||||||
$this->assertEquals($container2->getDefinitions(), $container1->getDefinitions(), 'loading a dump from a previously loaded container returns the same container');
|
$this->assertEquals($container2->getDefinitions(), $container1->getDefinitions(), 'loading a dump from a previously loaded container returns the same container');
|
||||||
$this->assertEquals($container2->getParameterBag()->all(), $container1->getParameterBag()->all(), '->getParameterBag() returns the same value for both containers');
|
$this->assertEquals($container2->getParameterBag()->all(), $container1->getParameterBag()->all(), '->getParameterBag() returns the same value for both containers');
|
||||||
|
|
||||||
|
$r = new \ReflectionProperty(ContainerBuilder::class, 'normalizedIds');
|
||||||
|
$r->setAccessible(true);
|
||||||
|
$r->setValue($container2, array());
|
||||||
|
$r->setValue($container1, array());
|
||||||
|
|
||||||
$this->assertEquals(serialize($container2), serialize($container1), 'loading a dump from a previously loaded container returns the same container');
|
$this->assertEquals(serialize($container2), serialize($container1), 'loading a dump from a previously loaded container returns the same container');
|
||||||
|
|
||||||
$services1 = array();
|
$services1 = array();
|
||||||
|
@ -484,4 +484,13 @@ class PhpDumperTest extends \PHPUnit_Framework_TestCase
|
|||||||
$res = $container->getResources();
|
$res = $container->getResources();
|
||||||
$this->assertSame(realpath(self::$fixturesPath.'/containers/container32.php'), array_pop($res)->getResource());
|
$this->assertSame(realpath(self::$fixturesPath.'/containers/container32.php'), array_pop($res)->getResource());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testNormalizedId()
|
||||||
|
{
|
||||||
|
$container = include self::$fixturesPath.'/containers/container33.php';
|
||||||
|
$container->compile();
|
||||||
|
$dumper = new PhpDumper($container);
|
||||||
|
|
||||||
|
$this->assertStringEqualsFile(self::$fixturesPath.'/php/services33.php', $dumper->dump());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Symfony\Component\DependencyInjection\Tests\Fixtures\Container33;
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\ClosureProxyArgument;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||||
|
|
||||||
|
if (!class_exists(Foo::class, false)) {
|
||||||
|
class Foo
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$container = new ContainerBuilder();
|
||||||
|
|
||||||
|
$container->register(Foo::class);
|
||||||
|
|
||||||
|
return $container;
|
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Symfony\Component\DependencyInjection\Argument\RewindableGenerator;
|
||||||
|
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||||
|
use Symfony\Component\DependencyInjection\Container;
|
||||||
|
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||||
|
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||||
|
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||||
|
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ProjectServiceContainer.
|
||||||
|
*
|
||||||
|
* This class has been auto-generated
|
||||||
|
* by the Symfony Dependency Injection Component.
|
||||||
|
*/
|
||||||
|
class ProjectServiceContainer extends Container
|
||||||
|
{
|
||||||
|
private $parameters;
|
||||||
|
private $targetDirs = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->services = array();
|
||||||
|
$this->normalizedIds = array(
|
||||||
|
'symfony\\component\\dependencyinjection\\tests\\fixtures\\container33\\foo' => 'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\Container33\\Foo',
|
||||||
|
);
|
||||||
|
$this->methodMap = array(
|
||||||
|
'Symfony\\Component\\DependencyInjection\\Tests\\Fixtures\\Container33\\Foo' => 'getSymfony_Component_DependencyInjection_Tests_Fixtures_Container33_FooService',
|
||||||
|
);
|
||||||
|
|
||||||
|
$this->aliases = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function compile()
|
||||||
|
{
|
||||||
|
throw new LogicException('You cannot compile a dumped frozen container.');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function isFrozen()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the 'Symfony\Component\DependencyInjection\Tests\Fixtures\Container33\Foo' service.
|
||||||
|
*
|
||||||
|
* This service is shared.
|
||||||
|
* This method always returns the same instance of the service.
|
||||||
|
*
|
||||||
|
* @return \Symfony\Component\DependencyInjection\Tests\Fixtures\Container33\Foo A Symfony\Component\DependencyInjection\Tests\Fixtures\Container33\Foo instance
|
||||||
|
*/
|
||||||
|
protected function getSymfony_Component_DependencyInjection_Tests_Fixtures_Container33_FooService()
|
||||||
|
{
|
||||||
|
return $this->services['Symfony\Component\DependencyInjection\Tests\Fixtures\Container33\Foo'] = new \Symfony\Component\DependencyInjection\Tests\Fixtures\Container33\Foo();
|
||||||
|
}
|
||||||
|
}
|
@ -20,10 +20,4 @@ class ReferenceTest extends \PHPUnit_Framework_TestCase
|
|||||||
$ref = new Reference('foo');
|
$ref = new Reference('foo');
|
||||||
$this->assertEquals('foo', (string) $ref, '__construct() sets the id of the reference, which is used for the __toString() method');
|
$this->assertEquals('foo', (string) $ref, '__construct() sets the id of the reference, which is used for the __toString() method');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testCaseInsensitive()
|
|
||||||
{
|
|
||||||
$ref = new Reference('FooBar');
|
|
||||||
$this->assertEquals('foobar', (string) $ref, 'the id is lowercased as the container is case insensitive');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user