Verzeichnisstruktur phpBB-3.3.15


Veröffentlicht
28.08.2024

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

(Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

ServiceLocator.php

Zuletzt modifiziert: 02.04.2025, 15:02 - Dateigröße: 4.63 KiB


001  <?php
002   
003  /*
004   * This file is part of the Symfony package.
005   *
006   * (c) Fabien Potencier <fabien@symfony.com>
007   *
008   * For the full copyright and license information, please view the LICENSE
009   * file that was distributed with this source code.
010   */
011   
012  namespace Symfony\Component\DependencyInjection;
013   
014  use Psr\Container\ContainerInterface as PsrContainerInterface;
015  use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
016  use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
017   
018  /**
019   * @author Robin Chalas <robin.chalas@gmail.com>
020   * @author Nicolas Grekas <p@tchwork.com>
021   */
022  class ServiceLocator implements PsrContainerInterface
023  {
024      private $factories;
025      private $loading = [];
026      private $externalId;
027      private $container;
028   
029      /**
030       * @param callable[] $factories
031       */
032      public function __construct(array $factories)
033      {
034          $this->factories = $factories;
035      }
036   
037      /**
038       * {@inheritdoc}
039       */
040      public function has($id)
041      {
042          return isset($this->factories[$id]);
043      }
044   
045      /**
046       * {@inheritdoc}
047       */
048      public function get($id)
049      {
050          if (!isset($this->factories[$id])) {
051              throw new ServiceNotFoundException($id, end($this->loading) ?: null, null, [], $this->createServiceNotFoundMessage($id));
052          }
053   
054          if (isset($this->loading[$id])) {
055              $ids = array_values($this->loading);
056              $ids = \array_slice($this->loading, array_search($id, $ids));
057              $ids[] = $id;
058   
059              throw new ServiceCircularReferenceException($id, $ids);
060          }
061   
062          $this->loading[$id] = $id;
063          try {
064              return $this->factories[$id]();
065          } finally {
066              unset($this->loading[$id]);
067          }
068      }
069   
070      public function __invoke($id)
071      {
072          return isset($this->factories[$id]) ? $this->get($id) : null;
073      }
074   
075      /**
076       * @internal
077       */
078      public function withContext($externalId, Container $container)
079      {
080          $locator = clone $this;
081          $locator->externalId = $externalId;
082          $locator->container = $container;
083   
084          return $locator;
085      }
086   
087      private function createServiceNotFoundMessage($id)
088      {
089          if ($this->loading) {
090              return sprintf('The service "%s" has a dependency on a non-existent service "%s". This locator %s', end($this->loading), $id, $this->formatAlternatives());
091          }
092   
093          $class = debug_backtrace(\DEBUG_BACKTRACE_PROVIDE_OBJECT | \DEBUG_BACKTRACE_IGNORE_ARGS, 3);
094          $class = isset($class[2]['object']) ? \get_class($class[2]['object']) : null;
095          $externalId = $this->externalId ?: $class;
096   
097          $msg = [];
098          $msg[] = sprintf('Service "%s" not found:', $id);
099   
100          if (!$this->container) {
101              $class = null;
102          } elseif ($this->container->has($id) || isset($this->container->getRemovedIds()[$id])) {
103              $msg[] = 'even though it exists in the app\'s container,';
104          } else {
105              try {
106                  $this->container->get($id);
107                  $class = null;
108              } catch (ServiceNotFoundException $e) {
109                  if ($e->getAlternatives()) {
110                      $msg[] = sprintf('did you mean %s? Anyway,', $this->formatAlternatives($e->getAlternatives(), 'or'));
111                  } else {
112                      $class = null;
113                  }
114              }
115          }
116          if ($externalId) {
117              $msg[] = sprintf('the container inside "%s" is a smaller service locator that %s', $externalId, $this->formatAlternatives());
118          } else {
119              $msg[] = sprintf('the current service locator %s', $this->formatAlternatives());
120          }
121   
122          if (!$class) {
123              // no-op
124          } elseif (is_subclass_of($class, ServiceSubscriberInterface::class)) {
125              $msg[] = sprintf('Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "%s::getSubscribedServices()".', preg_replace('/([^\\\\]++\\\\)++/', '', $class));
126          } else {
127              $msg[] = 'Try using dependency injection instead.';
128          }
129   
130          return implode(' ', $msg);
131      }
132   
133      private function formatAlternatives(array $alternatives = null, $separator = 'and')
134      {
135          $format = '"%s"%s';
136          if (null === $alternatives) {
137              if (!$alternatives = array_keys($this->factories)) {
138                  return 'is empty...';
139              }
140              $format = sprintf('only knows about the %s service%s.', $format, 1 < \count($alternatives) ? 's' : '');
141          }
142          $last = array_pop($alternatives);
143   
144          return sprintf($format, $alternatives ? implode('", "', $alternatives) : $last, $alternatives ? sprintf(' %s "%s"', $separator, $last) : '');
145      }
146  }
147