Verzeichnisstruktur phpBB-3.3.16


Veröffentlicht
27.04.2026

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: 01.05.2026, 11:26 - 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