annotate vendor/symfony/dependency-injection/Container.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents af1871eacc83
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 /*
Chris@0 4 * This file is part of the Symfony package.
Chris@0 5 *
Chris@0 6 * (c) Fabien Potencier <fabien@symfony.com>
Chris@0 7 *
Chris@0 8 * For the full copyright and license information, please view the LICENSE
Chris@0 9 * file that was distributed with this source code.
Chris@0 10 */
Chris@0 11
Chris@0 12 namespace Symfony\Component\DependencyInjection;
Chris@0 13
Chris@0 14 use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;
Chris@0 15 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
Chris@14 16 use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
Chris@17 17 use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
Chris@0 18 use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
Chris@0 19 use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
Chris@0 20 use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
Chris@17 21 use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
Chris@0 22
Chris@0 23 /**
Chris@0 24 * Container is a dependency injection container.
Chris@0 25 *
Chris@0 26 * It gives access to object instances (services).
Chris@0 27 * Services and parameters are simple key/pair stores.
Chris@14 28 * The container can have four possible behaviors when a service
Chris@14 29 * does not exist (or is not initialized for the last case):
Chris@0 30 *
Chris@0 31 * * EXCEPTION_ON_INVALID_REFERENCE: Throws an exception (the default)
Chris@0 32 * * NULL_ON_INVALID_REFERENCE: Returns null
Chris@0 33 * * IGNORE_ON_INVALID_REFERENCE: Ignores the wrapping command asking for the reference
Chris@0 34 * (for instance, ignore a setter if the service does not exist)
Chris@14 35 * * IGNORE_ON_UNINITIALIZED_REFERENCE: Ignores/returns null for uninitialized services or invalid references
Chris@0 36 *
Chris@0 37 * @author Fabien Potencier <fabien@symfony.com>
Chris@0 38 * @author Johannes M. Schmitt <schmittjoh@gmail.com>
Chris@0 39 */
Chris@0 40 class Container implements ResettableContainerInterface
Chris@0 41 {
Chris@0 42 protected $parameterBag;
Chris@17 43 protected $services = [];
Chris@17 44 protected $fileMap = [];
Chris@17 45 protected $methodMap = [];
Chris@17 46 protected $aliases = [];
Chris@17 47 protected $loading = [];
Chris@17 48 protected $resolving = [];
Chris@17 49 protected $syntheticIds = [];
Chris@0 50
Chris@12 51 /**
Chris@12 52 * @internal
Chris@12 53 */
Chris@17 54 protected $privates = [];
Chris@12 55
Chris@14 56 /**
Chris@14 57 * @internal
Chris@14 58 */
Chris@17 59 protected $normalizedIds = [];
Chris@14 60
Chris@17 61 private $underscoreMap = ['_' => '', '.' => '_', '\\' => '_'];
Chris@17 62 private $envCache = [];
Chris@14 63 private $compiled = false;
Chris@14 64 private $getEnv;
Chris@0 65
Chris@0 66 public function __construct(ParameterBagInterface $parameterBag = null)
Chris@0 67 {
Chris@0 68 $this->parameterBag = $parameterBag ?: new EnvPlaceholderParameterBag();
Chris@0 69 }
Chris@0 70
Chris@0 71 /**
Chris@0 72 * Compiles the container.
Chris@0 73 *
Chris@0 74 * This method does two things:
Chris@0 75 *
Chris@0 76 * * Parameter values are resolved;
Chris@0 77 * * The parameter bag is frozen.
Chris@0 78 */
Chris@0 79 public function compile()
Chris@0 80 {
Chris@0 81 $this->parameterBag->resolve();
Chris@0 82
Chris@0 83 $this->parameterBag = new FrozenParameterBag($this->parameterBag->all());
Chris@14 84
Chris@14 85 $this->compiled = true;
Chris@14 86 }
Chris@14 87
Chris@14 88 /**
Chris@14 89 * Returns true if the container is compiled.
Chris@14 90 *
Chris@14 91 * @return bool
Chris@14 92 */
Chris@14 93 public function isCompiled()
Chris@14 94 {
Chris@14 95 return $this->compiled;
Chris@0 96 }
Chris@0 97
Chris@0 98 /**
Chris@0 99 * Returns true if the container parameter bag are frozen.
Chris@0 100 *
Chris@14 101 * @deprecated since version 3.3, to be removed in 4.0.
Chris@14 102 *
Chris@0 103 * @return bool true if the container parameter bag are frozen, false otherwise
Chris@0 104 */
Chris@0 105 public function isFrozen()
Chris@0 106 {
Chris@14 107 @trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED);
Chris@14 108
Chris@0 109 return $this->parameterBag instanceof FrozenParameterBag;
Chris@0 110 }
Chris@0 111
Chris@0 112 /**
Chris@0 113 * Gets the service container parameter bag.
Chris@0 114 *
Chris@0 115 * @return ParameterBagInterface A ParameterBagInterface instance
Chris@0 116 */
Chris@0 117 public function getParameterBag()
Chris@0 118 {
Chris@0 119 return $this->parameterBag;
Chris@0 120 }
Chris@0 121
Chris@0 122 /**
Chris@0 123 * Gets a parameter.
Chris@0 124 *
Chris@0 125 * @param string $name The parameter name
Chris@0 126 *
Chris@0 127 * @return mixed The parameter value
Chris@0 128 *
Chris@0 129 * @throws InvalidArgumentException if the parameter is not defined
Chris@0 130 */
Chris@0 131 public function getParameter($name)
Chris@0 132 {
Chris@0 133 return $this->parameterBag->get($name);
Chris@0 134 }
Chris@0 135
Chris@0 136 /**
Chris@0 137 * Checks if a parameter exists.
Chris@0 138 *
Chris@0 139 * @param string $name The parameter name
Chris@0 140 *
Chris@0 141 * @return bool The presence of parameter in container
Chris@0 142 */
Chris@0 143 public function hasParameter($name)
Chris@0 144 {
Chris@0 145 return $this->parameterBag->has($name);
Chris@0 146 }
Chris@0 147
Chris@0 148 /**
Chris@0 149 * Sets a parameter.
Chris@0 150 *
Chris@0 151 * @param string $name The parameter name
Chris@0 152 * @param mixed $value The parameter value
Chris@0 153 */
Chris@0 154 public function setParameter($name, $value)
Chris@0 155 {
Chris@0 156 $this->parameterBag->set($name, $value);
Chris@0 157 }
Chris@0 158
Chris@0 159 /**
Chris@0 160 * Sets a service.
Chris@0 161 *
Chris@18 162 * Setting a synthetic service to null resets it: has() returns false and get()
Chris@0 163 * behaves in the same way as if the service was never created.
Chris@0 164 *
Chris@0 165 * @param string $id The service identifier
Chris@0 166 * @param object $service The service instance
Chris@0 167 */
Chris@0 168 public function set($id, $service)
Chris@0 169 {
Chris@14 170 // Runs the internal initializer; used by the dumped container to include always-needed files
Chris@14 171 if (isset($this->privates['service_container']) && $this->privates['service_container'] instanceof \Closure) {
Chris@14 172 $initialize = $this->privates['service_container'];
Chris@14 173 unset($this->privates['service_container']);
Chris@14 174 $initialize();
Chris@14 175 }
Chris@14 176
Chris@14 177 $id = $this->normalizeId($id);
Chris@0 178
Chris@0 179 if ('service_container' === $id) {
Chris@0 180 throw new InvalidArgumentException('You cannot set service "service_container".');
Chris@0 181 }
Chris@0 182
Chris@14 183 if (isset($this->privates[$id]) || !(isset($this->fileMap[$id]) || isset($this->methodMap[$id]))) {
Chris@14 184 if (!isset($this->privates[$id]) && !isset($this->getRemovedIds()[$id])) {
Chris@14 185 // no-op
Chris@14 186 } elseif (null === $service) {
Chris@14 187 @trigger_error(sprintf('The "%s" service is private, unsetting it is deprecated since Symfony 3.2 and will fail in 4.0.', $id), E_USER_DEPRECATED);
Chris@14 188 unset($this->privates[$id]);
Chris@14 189 } else {
Chris@14 190 @trigger_error(sprintf('The "%s" service is private, replacing it is deprecated since Symfony 3.2 and will fail in 4.0.', $id), E_USER_DEPRECATED);
Chris@14 191 }
Chris@14 192 } elseif (isset($this->services[$id])) {
Chris@14 193 if (null === $service) {
Chris@14 194 @trigger_error(sprintf('The "%s" service is already initialized, unsetting it is deprecated since Symfony 3.3 and will fail in 4.0.', $id), E_USER_DEPRECATED);
Chris@14 195 } else {
Chris@14 196 @trigger_error(sprintf('The "%s" service is already initialized, replacing it is deprecated since Symfony 3.3 and will fail in 4.0.', $id), E_USER_DEPRECATED);
Chris@14 197 }
Chris@14 198 }
Chris@14 199
Chris@0 200 if (isset($this->aliases[$id])) {
Chris@0 201 unset($this->aliases[$id]);
Chris@0 202 }
Chris@0 203
Chris@0 204 if (null === $service) {
Chris@0 205 unset($this->services[$id]);
Chris@14 206
Chris@14 207 return;
Chris@0 208 }
Chris@0 209
Chris@14 210 $this->services[$id] = $service;
Chris@0 211 }
Chris@0 212
Chris@0 213 /**
Chris@0 214 * Returns true if the given service is defined.
Chris@0 215 *
Chris@0 216 * @param string $id The service identifier
Chris@0 217 *
Chris@0 218 * @return bool true if the service is defined, false otherwise
Chris@0 219 */
Chris@0 220 public function has($id)
Chris@0 221 {
Chris@0 222 for ($i = 2;;) {
Chris@12 223 if (isset($this->privates[$id])) {
Chris@14 224 @trigger_error(sprintf('The "%s" service is private, checking for its existence is deprecated since Symfony 3.2 and will fail in 4.0.', $id), E_USER_DEPRECATED);
Chris@12 225 }
Chris@14 226 if (isset($this->aliases[$id])) {
Chris@14 227 $id = $this->aliases[$id];
Chris@14 228 }
Chris@14 229 if (isset($this->services[$id])) {
Chris@14 230 return true;
Chris@14 231 }
Chris@14 232 if ('service_container' === $id) {
Chris@0 233 return true;
Chris@0 234 }
Chris@0 235
Chris@14 236 if (isset($this->fileMap[$id]) || isset($this->methodMap[$id])) {
Chris@0 237 return true;
Chris@0 238 }
Chris@0 239
Chris@14 240 if (--$i && $id !== $normalizedId = $this->normalizeId($id)) {
Chris@14 241 $id = $normalizedId;
Chris@0 242 continue;
Chris@0 243 }
Chris@0 244
Chris@0 245 // We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder,
Chris@0 246 // and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper)
Chris@0 247 if (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class && method_exists($this, 'get'.strtr($id, $this->underscoreMap).'Service')) {
Chris@14 248 @trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', E_USER_DEPRECATED);
Chris@0 249
Chris@0 250 return true;
Chris@0 251 }
Chris@0 252
Chris@0 253 return false;
Chris@0 254 }
Chris@0 255 }
Chris@0 256
Chris@0 257 /**
Chris@0 258 * Gets a service.
Chris@0 259 *
Chris@0 260 * If a service is defined both through a set() method and
Chris@0 261 * with a get{$id}Service() method, the former has always precedence.
Chris@0 262 *
Chris@0 263 * @param string $id The service identifier
Chris@0 264 * @param int $invalidBehavior The behavior when the service does not exist
Chris@0 265 *
Chris@0 266 * @return object The associated service
Chris@0 267 *
Chris@0 268 * @throws ServiceCircularReferenceException When a circular reference is detected
Chris@0 269 * @throws ServiceNotFoundException When the service is not defined
Chris@0 270 * @throws \Exception if an exception has been thrown when the service has been resolved
Chris@0 271 *
Chris@0 272 * @see Reference
Chris@0 273 */
Chris@14 274 public function get($id, $invalidBehavior = /* self::EXCEPTION_ON_INVALID_REFERENCE */ 1)
Chris@0 275 {
Chris@0 276 // Attempt to retrieve the service by checking first aliases then
Chris@0 277 // available services. Service IDs are case insensitive, however since
Chris@0 278 // this method can be called thousands of times during a request, avoid
Chris@14 279 // calling $this->normalizeId($id) unless necessary.
Chris@0 280 for ($i = 2;;) {
Chris@12 281 if (isset($this->privates[$id])) {
Chris@14 282 @trigger_error(sprintf('The "%s" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead.', $id), E_USER_DEPRECATED);
Chris@0 283 }
Chris@0 284 if (isset($this->aliases[$id])) {
Chris@0 285 $id = $this->aliases[$id];
Chris@0 286 }
Chris@12 287
Chris@0 288 // Re-use shared service instance if it exists.
Chris@0 289 if (isset($this->services[$id])) {
Chris@0 290 return $this->services[$id];
Chris@0 291 }
Chris@12 292 if ('service_container' === $id) {
Chris@12 293 return $this;
Chris@12 294 }
Chris@0 295
Chris@0 296 if (isset($this->loading[$id])) {
Chris@17 297 throw new ServiceCircularReferenceException($id, array_merge(array_keys($this->loading), [$id]));
Chris@0 298 }
Chris@0 299
Chris@0 300 $this->loading[$id] = true;
Chris@0 301
Chris@0 302 try {
Chris@14 303 if (isset($this->fileMap[$id])) {
Chris@14 304 return /* self::IGNORE_ON_UNINITIALIZED_REFERENCE */ 4 === $invalidBehavior ? null : $this->load($this->fileMap[$id]);
Chris@14 305 } elseif (isset($this->methodMap[$id])) {
Chris@14 306 return /* self::IGNORE_ON_UNINITIALIZED_REFERENCE */ 4 === $invalidBehavior ? null : $this->{$this->methodMap[$id]}();
Chris@14 307 } elseif (--$i && $id !== $normalizedId = $this->normalizeId($id)) {
Chris@14 308 unset($this->loading[$id]);
Chris@14 309 $id = $normalizedId;
Chris@14 310 continue;
Chris@14 311 } elseif (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class && method_exists($this, $method = 'get'.strtr($id, $this->underscoreMap).'Service')) {
Chris@14 312 // We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder,
Chris@14 313 // and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper)
Chris@14 314 @trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', E_USER_DEPRECATED);
Chris@14 315
Chris@14 316 return /* self::IGNORE_ON_UNINITIALIZED_REFERENCE */ 4 === $invalidBehavior ? null : $this->{$method}();
Chris@14 317 }
Chris@14 318
Chris@14 319 break;
Chris@0 320 } catch (\Exception $e) {
Chris@0 321 unset($this->services[$id]);
Chris@0 322
Chris@0 323 throw $e;
Chris@0 324 } finally {
Chris@0 325 unset($this->loading[$id]);
Chris@0 326 }
Chris@14 327 }
Chris@0 328
Chris@14 329 if (/* self::EXCEPTION_ON_INVALID_REFERENCE */ 1 === $invalidBehavior) {
Chris@14 330 if (!$id) {
Chris@14 331 throw new ServiceNotFoundException($id);
Chris@14 332 }
Chris@14 333 if (isset($this->syntheticIds[$id])) {
Chris@17 334 throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service is synthetic, it needs to be set at boot time before it can be used.', $id));
Chris@14 335 }
Chris@14 336 if (isset($this->getRemovedIds()[$id])) {
Chris@17 337 throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.', $id));
Chris@14 338 }
Chris@14 339
Chris@17 340 $alternatives = [];
Chris@14 341 foreach ($this->getServiceIds() as $knownId) {
Chris@14 342 $lev = levenshtein($id, $knownId);
Chris@17 343 if ($lev <= \strlen($id) / 3 || false !== strpos($knownId, $id)) {
Chris@14 344 $alternatives[] = $knownId;
Chris@14 345 }
Chris@14 346 }
Chris@14 347
Chris@14 348 throw new ServiceNotFoundException($id, null, null, $alternatives);
Chris@0 349 }
Chris@0 350 }
Chris@0 351
Chris@0 352 /**
Chris@0 353 * Returns true if the given service has actually been initialized.
Chris@0 354 *
Chris@0 355 * @param string $id The service identifier
Chris@0 356 *
Chris@0 357 * @return bool true if service has already been initialized, false otherwise
Chris@0 358 */
Chris@0 359 public function initialized($id)
Chris@0 360 {
Chris@14 361 $id = $this->normalizeId($id);
Chris@14 362
Chris@14 363 if (isset($this->privates[$id])) {
Chris@14 364 @trigger_error(sprintf('Checking for the initialization of the "%s" private service is deprecated since Symfony 3.4 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED);
Chris@14 365 }
Chris@0 366
Chris@12 367 if (isset($this->aliases[$id])) {
Chris@12 368 $id = $this->aliases[$id];
Chris@12 369 }
Chris@12 370
Chris@0 371 if ('service_container' === $id) {
Chris@0 372 return false;
Chris@0 373 }
Chris@0 374
Chris@0 375 return isset($this->services[$id]);
Chris@0 376 }
Chris@0 377
Chris@0 378 /**
Chris@0 379 * {@inheritdoc}
Chris@0 380 */
Chris@0 381 public function reset()
Chris@0 382 {
Chris@17 383 $this->services = [];
Chris@0 384 }
Chris@0 385
Chris@0 386 /**
Chris@0 387 * Gets all service ids.
Chris@0 388 *
Chris@0 389 * @return array An array of all defined service ids
Chris@0 390 */
Chris@0 391 public function getServiceIds()
Chris@0 392 {
Chris@17 393 $ids = [];
Chris@0 394
Chris@0 395 if (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class) {
Chris@0 396 // We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder,
Chris@0 397 // and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper)
Chris@14 398 @trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', E_USER_DEPRECATED);
Chris@0 399
Chris@0 400 foreach (get_class_methods($this) as $method) {
Chris@0 401 if (preg_match('/^get(.+)Service$/', $method, $match)) {
Chris@0 402 $ids[] = self::underscore($match[1]);
Chris@0 403 }
Chris@0 404 }
Chris@0 405 }
Chris@0 406 $ids[] = 'service_container';
Chris@0 407
Chris@14 408 return array_unique(array_merge($ids, array_keys($this->methodMap), array_keys($this->fileMap), array_keys($this->services)));
Chris@14 409 }
Chris@14 410
Chris@14 411 /**
Chris@14 412 * Gets service ids that existed at compile time.
Chris@14 413 *
Chris@14 414 * @return array
Chris@14 415 */
Chris@14 416 public function getRemovedIds()
Chris@14 417 {
Chris@17 418 return [];
Chris@0 419 }
Chris@0 420
Chris@0 421 /**
Chris@0 422 * Camelizes a string.
Chris@0 423 *
Chris@0 424 * @param string $id A string to camelize
Chris@0 425 *
Chris@0 426 * @return string The camelized string
Chris@0 427 */
Chris@0 428 public static function camelize($id)
Chris@0 429 {
Chris@17 430 return strtr(ucwords(strtr($id, ['_' => ' ', '.' => '_ ', '\\' => '_ '])), [' ' => '']);
Chris@0 431 }
Chris@0 432
Chris@0 433 /**
Chris@0 434 * A string to underscore.
Chris@0 435 *
Chris@0 436 * @param string $id The string to underscore
Chris@0 437 *
Chris@0 438 * @return string The underscored string
Chris@0 439 */
Chris@0 440 public static function underscore($id)
Chris@0 441 {
Chris@17 442 return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], str_replace('_', '.', $id)));
Chris@0 443 }
Chris@0 444
Chris@0 445 /**
Chris@14 446 * Creates a service by requiring its factory file.
Chris@14 447 *
Chris@14 448 * @return object The service created by the file
Chris@14 449 */
Chris@14 450 protected function load($file)
Chris@14 451 {
Chris@14 452 return require $file;
Chris@14 453 }
Chris@14 454
Chris@14 455 /**
Chris@0 456 * Fetches a variable from the environment.
Chris@0 457 *
Chris@14 458 * @param string $name The name of the environment variable
Chris@0 459 *
Chris@14 460 * @return mixed The value to use for the provided environment variable name
Chris@0 461 *
Chris@0 462 * @throws EnvNotFoundException When the environment variable is not found and has no default value
Chris@0 463 */
Chris@0 464 protected function getEnv($name)
Chris@0 465 {
Chris@14 466 if (isset($this->resolving[$envName = "env($name)"])) {
Chris@14 467 throw new ParameterCircularReferenceException(array_keys($this->resolving));
Chris@14 468 }
Chris@18 469 if (isset($this->envCache[$name]) || \array_key_exists($name, $this->envCache)) {
Chris@0 470 return $this->envCache[$name];
Chris@0 471 }
Chris@14 472 if (!$this->has($id = 'container.env_var_processors_locator')) {
Chris@17 473 $this->set($id, new ServiceLocator([]));
Chris@0 474 }
Chris@14 475 if (!$this->getEnv) {
Chris@14 476 $this->getEnv = new \ReflectionMethod($this, __FUNCTION__);
Chris@14 477 $this->getEnv->setAccessible(true);
Chris@14 478 $this->getEnv = $this->getEnv->getClosure($this);
Chris@0 479 }
Chris@14 480 $processors = $this->get($id);
Chris@14 481
Chris@14 482 if (false !== $i = strpos($name, ':')) {
Chris@14 483 $prefix = substr($name, 0, $i);
Chris@14 484 $localName = substr($name, 1 + $i);
Chris@14 485 } else {
Chris@14 486 $prefix = 'string';
Chris@14 487 $localName = $name;
Chris@14 488 }
Chris@14 489 $processor = $processors->has($prefix) ? $processors->get($prefix) : new EnvVarProcessor($this);
Chris@14 490
Chris@14 491 $this->resolving[$envName] = true;
Chris@14 492 try {
Chris@14 493 return $this->envCache[$name] = $processor->getEnv($prefix, $localName, $this->getEnv);
Chris@14 494 } finally {
Chris@14 495 unset($this->resolving[$envName]);
Chris@14 496 }
Chris@14 497 }
Chris@14 498
Chris@14 499 /**
Chris@14 500 * Returns the case sensitive id used at registration time.
Chris@14 501 *
Chris@14 502 * @param string $id
Chris@14 503 *
Chris@14 504 * @return string
Chris@14 505 *
Chris@14 506 * @internal
Chris@14 507 */
Chris@14 508 public function normalizeId($id)
Chris@14 509 {
Chris@14 510 if (!\is_string($id)) {
Chris@14 511 $id = (string) $id;
Chris@14 512 }
Chris@14 513 if (isset($this->normalizedIds[$normalizedId = strtolower($id)])) {
Chris@14 514 $normalizedId = $this->normalizedIds[$normalizedId];
Chris@14 515 if ($id !== $normalizedId) {
Chris@14 516 @trigger_error(sprintf('Service identifiers will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.3.', $id, $normalizedId), E_USER_DEPRECATED);
Chris@14 517 }
Chris@14 518 } else {
Chris@14 519 $normalizedId = $this->normalizedIds[$normalizedId] = $id;
Chris@0 520 }
Chris@0 521
Chris@14 522 return $normalizedId;
Chris@0 523 }
Chris@0 524
Chris@0 525 private function __clone()
Chris@0 526 {
Chris@0 527 }
Chris@0 528 }