Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

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

Container.php

Zuletzt modifiziert: 09.10.2024, 12:54 - Dateigröße: 19.54 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 Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
 015  use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
 016  use Symfony\Component\DependencyInjection\Exception\LogicException;
 017  use Symfony\Component\DependencyInjection\Exception\RuntimeException;
 018  use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
 019  use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
 020  use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
 021  use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
 022  use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
 023   
 024  /**
 025   * Container is a dependency injection container.
 026   *
 027   * It gives access to object instances (services).
 028   *
 029   * Services and parameters are simple key/pair stores.
 030   *
 031   * Parameter and service keys are case insensitive.
 032   *
 033   * A service id can contain lowercased letters, digits, underscores, and dots.
 034   * Underscores are used to separate words, and dots to group services
 035   * under namespaces:
 036   *
 037   * <ul>
 038   *   <li>request</li>
 039   *   <li>mysql_session_storage</li>
 040   *   <li>symfony.mysql_session_storage</li>
 041   * </ul>
 042   *
 043   * A service can also be defined by creating a method named
 044   * getXXXService(), where XXX is the camelized version of the id:
 045   *
 046   * <ul>
 047   *   <li>request -> getRequestService()</li>
 048   *   <li>mysql_session_storage -> getMysqlSessionStorageService()</li>
 049   *   <li>symfony.mysql_session_storage -> getSymfony_MysqlSessionStorageService()</li>
 050   * </ul>
 051   *
 052   * The container can have three possible behaviors when a service does not exist:
 053   *
 054   *  * EXCEPTION_ON_INVALID_REFERENCE: Throws an exception (the default)
 055   *  * NULL_ON_INVALID_REFERENCE:      Returns null
 056   *  * IGNORE_ON_INVALID_REFERENCE:    Ignores the wrapping command asking for the reference
 057   *                                    (for instance, ignore a setter if the service does not exist)
 058   *
 059   * @author Fabien Potencier <fabien@symfony.com>
 060   * @author Johannes M. Schmitt <schmittjoh@gmail.com>
 061   */
 062  class Container implements IntrospectableContainerInterface, ResettableContainerInterface
 063  {
 064      /**
 065       * @var ParameterBagInterface
 066       */
 067      protected $parameterBag;
 068   
 069      protected $services = array();
 070      protected $methodMap = array();
 071      protected $aliases = array();
 072      protected $scopes = array();
 073      protected $scopeChildren = array();
 074      protected $scopedServices = array();
 075      protected $scopeStacks = array();
 076      protected $loading = array();
 077   
 078      private $underscoreMap = array('_' => '', '.' => '_', '\\' => '_');
 079   
 080      /**
 081       * @param ParameterBagInterface $parameterBag A ParameterBagInterface instance
 082       */
 083      public function __construct(ParameterBagInterface $parameterBag = null)
 084      {
 085          $this->parameterBag = $parameterBag ?: new ParameterBag();
 086      }
 087   
 088      /**
 089       * Compiles the container.
 090       *
 091       * This method does two things:
 092       *
 093       *  * Parameter values are resolved;
 094       *  * The parameter bag is frozen.
 095       */
 096      public function compile()
 097      {
 098          $this->parameterBag->resolve();
 099   
 100          $this->parameterBag = new FrozenParameterBag($this->parameterBag->all());
 101      }
 102   
 103      /**
 104       * Returns true if the container parameter bag are frozen.
 105       *
 106       * @return bool true if the container parameter bag are frozen, false otherwise
 107       */
 108      public function isFrozen()
 109      {
 110          return $this->parameterBag instanceof FrozenParameterBag;
 111      }
 112   
 113      /**
 114       * Gets the service container parameter bag.
 115       *
 116       * @return ParameterBagInterface A ParameterBagInterface instance
 117       */
 118      public function getParameterBag()
 119      {
 120          return $this->parameterBag;
 121      }
 122   
 123      /**
 124       * Gets a parameter.
 125       *
 126       * @param string $name The parameter name
 127       *
 128       * @return mixed The parameter value
 129       *
 130       * @throws InvalidArgumentException if the parameter is not defined
 131       */
 132      public function getParameter($name)
 133      {
 134          return $this->parameterBag->get($name);
 135      }
 136   
 137      /**
 138       * Checks if a parameter exists.
 139       *
 140       * @param string $name The parameter name
 141       *
 142       * @return bool The presence of parameter in container
 143       */
 144      public function hasParameter($name)
 145      {
 146          return $this->parameterBag->has($name);
 147      }
 148   
 149      /**
 150       * Sets a parameter.
 151       *
 152       * @param string $name  The parameter name
 153       * @param mixed  $value The parameter value
 154       */
 155      public function setParameter($name, $value)
 156      {
 157          $this->parameterBag->set($name, $value);
 158      }
 159   
 160      /**
 161       * Sets a service.
 162       *
 163       * Setting a service to null resets the service: has() returns false and get()
 164       * behaves in the same way as if the service was never created.
 165       *
 166       * Note: The $scope parameter is deprecated since version 2.8 and will be removed in 3.0.
 167       *
 168       * @param string $id      The service identifier
 169       * @param object $service The service instance
 170       * @param string $scope   The scope of the service
 171       *
 172       * @throws RuntimeException         When trying to set a service in an inactive scope
 173       * @throws InvalidArgumentException When trying to set a service in the prototype scope
 174       */
 175      public function set($id, $service, $scope = self::SCOPE_CONTAINER)
 176      {
 177          if (!in_array($scope, array('container', 'request')) || ('request' === $scope && 'request' !== $id)) {
 178              @trigger_error('The concept of container scopes is deprecated since version 2.8 and will be removed in 3.0. Omit the third parameter.', E_USER_DEPRECATED);
 179          }
 180   
 181          if (self::SCOPE_PROTOTYPE === $scope) {
 182              throw new InvalidArgumentException(sprintf('You cannot set service "%s" of scope "prototype".', $id));
 183          }
 184   
 185          $id = strtolower($id);
 186   
 187          if ('service_container' === $id) {
 188              // BC: 'service_container' is no longer a self-reference but always
 189              // $this, so ignore this call.
 190              // @todo Throw InvalidArgumentException in next major release.
 191              return;
 192          }
 193          if (self::SCOPE_CONTAINER !== $scope) {
 194              if (!isset($this->scopedServices[$scope])) {
 195                  throw new RuntimeException(sprintf('You cannot set service "%s" of inactive scope.', $id));
 196              }
 197   
 198              $this->scopedServices[$scope][$id] = $service;
 199          }
 200   
 201          if (isset($this->aliases[$id])) {
 202              unset($this->aliases[$id]);
 203          }
 204   
 205          $this->services[$id] = $service;
 206   
 207          if (method_exists($this, $method = 'synchronize'.strtr($id, $this->underscoreMap).'Service')) {
 208              $this->$method();
 209          }
 210   
 211          if (null === $service) {
 212              if (self::SCOPE_CONTAINER !== $scope) {
 213                  unset($this->scopedServices[$scope][$id]);
 214              }
 215   
 216              unset($this->services[$id]);
 217          }
 218      }
 219   
 220      /**
 221       * Returns true if the given service is defined.
 222       *
 223       * @param string $id The service identifier
 224       *
 225       * @return bool true if the service is defined, false otherwise
 226       */
 227      public function has($id)
 228      {
 229          for ($i = 2;;) {
 230              if ('service_container' === $id
 231                  || isset($this->aliases[$id])
 232                  || isset($this->services[$id])
 233                  || array_key_exists($id, $this->services)
 234              ) {
 235                  return true;
 236              }
 237              if (--$i && $id !== $lcId = strtolower($id)) {
 238                  $id = $lcId;
 239              } else {
 240                  return method_exists($this, 'get'.strtr($id, $this->underscoreMap).'Service');
 241              }
 242          }
 243      }
 244   
 245      /**
 246       * Gets a service.
 247       *
 248       * If a service is defined both through a set() method and
 249       * with a get{$id}Service() method, the former has always precedence.
 250       *
 251       * @param string $id              The service identifier
 252       * @param int    $invalidBehavior The behavior when the service does not exist
 253       *
 254       * @return object The associated service
 255       *
 256       * @throws ServiceCircularReferenceException When a circular reference is detected
 257       * @throws ServiceNotFoundException          When the service is not defined
 258       * @throws \Exception                        if an exception has been thrown when the service has been resolved
 259       *
 260       * @see Reference
 261       */
 262      public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE)
 263      {
 264          // Attempt to retrieve the service by checking first aliases then
 265          // available services. Service IDs are case insensitive, however since
 266          // this method can be called thousands of times during a request, avoid
 267          // calling strtolower() unless necessary.
 268          for ($i = 2;;) {
 269              if ('service_container' === $id) {
 270                  return $this;
 271              }
 272              if (isset($this->aliases[$id])) {
 273                  $id = $this->aliases[$id];
 274              }
 275              // Re-use shared service instance if it exists.
 276              if (isset($this->services[$id]) || array_key_exists($id, $this->services)) {
 277                  return $this->services[$id];
 278              }
 279   
 280              if (isset($this->loading[$id])) {
 281                  throw new ServiceCircularReferenceException($id, array_keys($this->loading));
 282              }
 283   
 284              if (isset($this->methodMap[$id])) {
 285                  $method = $this->methodMap[$id];
 286              } elseif (--$i && $id !== $lcId = strtolower($id)) {
 287                  $id = $lcId;
 288                  continue;
 289              } elseif (method_exists($this, $method = 'get'.strtr($id, $this->underscoreMap).'Service')) {
 290                  // $method is set to the right value, proceed
 291              } else {
 292                  if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) {
 293                      if (!$id) {
 294                          throw new ServiceNotFoundException($id);
 295                      }
 296   
 297                      $alternatives = array();
 298                      foreach ($this->getServiceIds() as $knownId) {
 299                          $lev = levenshtein($id, $knownId);
 300                          if ($lev <= strlen($id) / 3 || false !== strpos($knownId, $id)) {
 301                              $alternatives[] = $knownId;
 302                          }
 303                      }
 304   
 305                      throw new ServiceNotFoundException($id, null, null, $alternatives);
 306                  }
 307   
 308                  return;
 309              }
 310   
 311              $this->loading[$id] = true;
 312   
 313              try {
 314                  $service = $this->$method();
 315              } catch (\Exception $e) {
 316                  unset($this->loading[$id]);
 317                  unset($this->services[$id]);
 318   
 319                  if ($e instanceof InactiveScopeException && self::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) {
 320                      return;
 321                  }
 322   
 323                  throw $e;
 324              } catch (\Throwable $e) {
 325                  unset($this->loading[$id]);
 326                  unset($this->services[$id]);
 327   
 328                  throw $e;
 329              }
 330   
 331              unset($this->loading[$id]);
 332   
 333              return $service;
 334          }
 335      }
 336   
 337      /**
 338       * Returns true if the given service has actually been initialized.
 339       *
 340       * @param string $id The service identifier
 341       *
 342       * @return bool true if service has already been initialized, false otherwise
 343       */
 344      public function initialized($id)
 345      {
 346          $id = strtolower($id);
 347   
 348          if ('service_container' === $id) {
 349              // BC: 'service_container' was a synthetic service previously.
 350              // @todo Change to false in next major release.
 351              return true;
 352          }
 353   
 354          if (isset($this->aliases[$id])) {
 355              $id = $this->aliases[$id];
 356          }
 357   
 358          return isset($this->services[$id]) || array_key_exists($id, $this->services);
 359      }
 360   
 361      /**
 362       * {@inheritdoc}
 363       */
 364      public function reset()
 365      {
 366          if (!empty($this->scopedServices)) {
 367              throw new LogicException('Resetting the container is not allowed when a scope is active.');
 368          }
 369   
 370          $this->services = array();
 371      }
 372   
 373      /**
 374       * Gets all service ids.
 375       *
 376       * @return array An array of all defined service ids
 377       */
 378      public function getServiceIds()
 379      {
 380          $ids = array();
 381          foreach (get_class_methods($this) as $method) {
 382              if (preg_match('/^get(.+)Service$/', $method, $match)) {
 383                  $ids[] = self::underscore($match[1]);
 384              }
 385          }
 386          $ids[] = 'service_container';
 387   
 388          return array_unique(array_merge($ids, array_keys($this->services)));
 389      }
 390   
 391      /**
 392       * This is called when you enter a scope.
 393       *
 394       * @param string $name
 395       *
 396       * @throws RuntimeException         When the parent scope is inactive
 397       * @throws InvalidArgumentException When the scope does not exist
 398       *
 399       * @deprecated since version 2.8, to be removed in 3.0.
 400       */
 401      public function enterScope($name)
 402      {
 403          if ('request' !== $name) {
 404              @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
 405          }
 406   
 407          if (!isset($this->scopes[$name])) {
 408              throw new InvalidArgumentException(sprintf('The scope "%s" does not exist.', $name));
 409          }
 410   
 411          if (self::SCOPE_CONTAINER !== $this->scopes[$name] && !isset($this->scopedServices[$this->scopes[$name]])) {
 412              throw new RuntimeException(sprintf('The parent scope "%s" must be active when entering this scope.', $this->scopes[$name]));
 413          }
 414   
 415          // check if a scope of this name is already active, if so we need to
 416          // remove all services of this scope, and those of any of its child
 417          // scopes from the global services map
 418          if (isset($this->scopedServices[$name])) {
 419              $services = array($this->services, $name => $this->scopedServices[$name]);
 420              unset($this->scopedServices[$name]);
 421   
 422              foreach ($this->scopeChildren[$name] as $child) {
 423                  if (isset($this->scopedServices[$child])) {
 424                      $services[$child] = $this->scopedServices[$child];
 425                      unset($this->scopedServices[$child]);
 426                  }
 427              }
 428   
 429              // update global map
 430              $this->services = call_user_func_array('array_diff_key', $services);
 431              array_shift($services);
 432   
 433              // add stack entry for this scope so we can restore the removed services later
 434              if (!isset($this->scopeStacks[$name])) {
 435                  $this->scopeStacks[$name] = new \SplStack();
 436              }
 437              $this->scopeStacks[$name]->push($services);
 438          }
 439   
 440          $this->scopedServices[$name] = array();
 441      }
 442   
 443      /**
 444       * This is called to leave the current scope, and move back to the parent
 445       * scope.
 446       *
 447       * @param string $name The name of the scope to leave
 448       *
 449       * @throws InvalidArgumentException if the scope is not active
 450       *
 451       * @deprecated since version 2.8, to be removed in 3.0.
 452       */
 453      public function leaveScope($name)
 454      {
 455          if ('request' !== $name) {
 456              @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
 457          }
 458   
 459          if (!isset($this->scopedServices[$name])) {
 460              throw new InvalidArgumentException(sprintf('The scope "%s" is not active.', $name));
 461          }
 462   
 463          // remove all services of this scope, or any of its child scopes from
 464          // the global service map
 465          $services = array($this->services, $this->scopedServices[$name]);
 466          unset($this->scopedServices[$name]);
 467   
 468          foreach ($this->scopeChildren[$name] as $child) {
 469              if (isset($this->scopedServices[$child])) {
 470                  $services[] = $this->scopedServices[$child];
 471                  unset($this->scopedServices[$child]);
 472              }
 473          }
 474   
 475          // update global map
 476          $this->services = call_user_func_array('array_diff_key', $services);
 477   
 478          // check if we need to restore services of a previous scope of this type
 479          if (isset($this->scopeStacks[$name]) && count($this->scopeStacks[$name]) > 0) {
 480              $services = $this->scopeStacks[$name]->pop();
 481              $this->scopedServices += $services;
 482   
 483              if ($this->scopeStacks[$name]->isEmpty()) {
 484                  unset($this->scopeStacks[$name]);
 485              }
 486   
 487              foreach ($services as $array) {
 488                  foreach ($array as $id => $service) {
 489                      $this->set($id, $service, $name);
 490                  }
 491              }
 492          }
 493      }
 494   
 495      /**
 496       * Adds a scope to the container.
 497       *
 498       * @param ScopeInterface $scope
 499       *
 500       * @throws InvalidArgumentException
 501       *
 502       * @deprecated since version 2.8, to be removed in 3.0.
 503       */
 504      public function addScope(ScopeInterface $scope)
 505      {
 506          $name = $scope->getName();
 507          $parentScope = $scope->getParentName();
 508   
 509          if ('request' !== $name) {
 510              @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
 511          }
 512          if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) {
 513              throw new InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name));
 514          }
 515          if (isset($this->scopes[$name])) {
 516              throw new InvalidArgumentException(sprintf('A scope with name "%s" already exists.', $name));
 517          }
 518          if (self::SCOPE_CONTAINER !== $parentScope && !isset($this->scopes[$parentScope])) {
 519              throw new InvalidArgumentException(sprintf('The parent scope "%s" does not exist, or is invalid.', $parentScope));
 520          }
 521   
 522          $this->scopes[$name] = $parentScope;
 523          $this->scopeChildren[$name] = array();
 524   
 525          // normalize the child relations
 526          while ($parentScope !== self::SCOPE_CONTAINER) {
 527              $this->scopeChildren[$parentScope][] = $name;
 528              $parentScope = $this->scopes[$parentScope];
 529          }
 530      }
 531   
 532      /**
 533       * Returns whether this container has a certain scope.
 534       *
 535       * @param string $name The name of the scope
 536       *
 537       * @return bool
 538       *
 539       * @deprecated since version 2.8, to be removed in 3.0.
 540       */
 541      public function hasScope($name)
 542      {
 543          if ('request' !== $name) {
 544              @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
 545          }
 546   
 547          return isset($this->scopes[$name]);
 548      }
 549   
 550      /**
 551       * Returns whether this scope is currently active.
 552       *
 553       * This does not actually check if the passed scope actually exists.
 554       *
 555       * @param string $name
 556       *
 557       * @return bool
 558       *
 559       * @deprecated since version 2.8, to be removed in 3.0.
 560       */
 561      public function isScopeActive($name)
 562      {
 563          @trigger_error('The '.__METHOD__.' method is deprecated since version 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
 564   
 565          return isset($this->scopedServices[$name]);
 566      }
 567   
 568      /**
 569       * Camelizes a string.
 570       *
 571       * @param string $id A string to camelize
 572       *
 573       * @return string The camelized string
 574       */
 575      public static function camelize($id)
 576      {
 577          return strtr(ucwords(strtr($id, array('_' => ' ', '.' => '_ ', '\\' => '_ '))), array(' ' => ''));
 578      }
 579   
 580      /**
 581       * A string to underscore.
 582       *
 583       * @param string $id The string to underscore
 584       *
 585       * @return string The underscored string
 586       */
 587      public static function underscore($id)
 588      {
 589          return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), str_replace('_', '.', $id)));
 590      }
 591   
 592      private function __clone()
 593      {
 594      }
 595  }
 596