[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/symfony/http-kernel/ -> Kernel.php (source)

   1  <?php
   2  
   3  /*
   4   * This file is part of the Symfony package.
   5   *
   6   * (c) Fabien Potencier <fabien@symfony.com>
   7   *
   8   * For the full copyright and license information, please view the LICENSE
   9   * file that was distributed with this source code.
  10   */
  11  
  12  namespace Symfony\Component\HttpKernel;
  13  
  14  use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator;
  15  use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
  16  use Symfony\Component\ClassLoader\ClassCollectionLoader;
  17  use Symfony\Component\Config\ConfigCache;
  18  use Symfony\Component\Config\Loader\DelegatingLoader;
  19  use Symfony\Component\Config\Loader\LoaderResolver;
  20  use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  21  use Symfony\Component\DependencyInjection\Compiler\PassConfig;
  22  use Symfony\Component\DependencyInjection\ContainerBuilder;
  23  use Symfony\Component\DependencyInjection\ContainerInterface;
  24  use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
  25  use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
  26  use Symfony\Component\DependencyInjection\Loader\DirectoryLoader;
  27  use Symfony\Component\DependencyInjection\Loader\GlobFileLoader;
  28  use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
  29  use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
  30  use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
  31  use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
  32  use Symfony\Component\Filesystem\Filesystem;
  33  use Symfony\Component\HttpFoundation\Request;
  34  use Symfony\Component\HttpFoundation\Response;
  35  use Symfony\Component\HttpKernel\Bundle\BundleInterface;
  36  use Symfony\Component\HttpKernel\Config\EnvParametersResource;
  37  use Symfony\Component\HttpKernel\Config\FileLocator;
  38  use Symfony\Component\HttpKernel\DependencyInjection\AddAnnotatedClassesToCachePass;
  39  use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
  40  
  41  /**
  42   * The Kernel is the heart of the Symfony system.
  43   *
  44   * It manages an environment made of bundles.
  45   *
  46   * @author Fabien Potencier <fabien@symfony.com>
  47   */
  48  abstract class Kernel implements KernelInterface, RebootableInterface, TerminableInterface
  49  {
  50      /**
  51       * @var BundleInterface[]
  52       */
  53      protected $bundles = [];
  54  
  55      protected $bundleMap;
  56      protected $container;
  57      protected $rootDir;
  58      protected $environment;
  59      protected $debug;
  60      protected $booted = false;
  61      protected $name;
  62      protected $startTime;
  63      protected $loadClassCache;
  64  
  65      private $projectDir;
  66      private $warmupDir;
  67      private $requestStackSize = 0;
  68      private $resetServices = false;
  69  
  70      const VERSION = '3.4.49';
  71      const VERSION_ID = 30449;
  72      const MAJOR_VERSION = 3;
  73      const MINOR_VERSION = 4;
  74      const RELEASE_VERSION = 49;
  75      const EXTRA_VERSION = '';
  76  
  77      const END_OF_MAINTENANCE = '11/2020';
  78      const END_OF_LIFE = '11/2021';
  79  
  80      /**
  81       * @param string $environment The environment
  82       * @param bool   $debug       Whether to enable debugging or not
  83       */
  84      public function __construct($environment, $debug)
  85      {
  86          $this->environment = $environment;
  87          $this->debug = (bool) $debug;
  88          $this->rootDir = $this->getRootDir();
  89          $this->name = $this->getName();
  90      }
  91  
  92      public function __clone()
  93      {
  94          $this->booted = false;
  95          $this->container = null;
  96          $this->requestStackSize = 0;
  97          $this->resetServices = false;
  98      }
  99  
 100      /**
 101       * {@inheritdoc}
 102       */
 103      public function boot()
 104      {
 105          if (true === $this->booted) {
 106              if (!$this->requestStackSize && $this->resetServices) {
 107                  if ($this->container->has('services_resetter')) {
 108                      $this->container->get('services_resetter')->reset();
 109                  }
 110                  $this->resetServices = false;
 111                  if ($this->debug) {
 112                      $this->startTime = microtime(true);
 113                  }
 114              }
 115  
 116              return;
 117          }
 118          if ($this->debug) {
 119              $this->startTime = microtime(true);
 120          }
 121          if ($this->debug && !isset($_ENV['SHELL_VERBOSITY']) && !isset($_SERVER['SHELL_VERBOSITY'])) {
 122              putenv('SHELL_VERBOSITY=3');
 123              $_ENV['SHELL_VERBOSITY'] = 3;
 124              $_SERVER['SHELL_VERBOSITY'] = 3;
 125          }
 126  
 127          if ($this->loadClassCache) {
 128              $this->doLoadClassCache($this->loadClassCache[0], $this->loadClassCache[1]);
 129          }
 130  
 131          // init bundles
 132          $this->initializeBundles();
 133  
 134          // init container
 135          $this->initializeContainer();
 136  
 137          foreach ($this->getBundles() as $bundle) {
 138              $bundle->setContainer($this->container);
 139              $bundle->boot();
 140          }
 141  
 142          $this->booted = true;
 143      }
 144  
 145      /**
 146       * {@inheritdoc}
 147       */
 148      public function reboot($warmupDir)
 149      {
 150          $this->shutdown();
 151          $this->warmupDir = $warmupDir;
 152          $this->boot();
 153      }
 154  
 155      /**
 156       * {@inheritdoc}
 157       */
 158      public function terminate(Request $request, Response $response)
 159      {
 160          if (false === $this->booted) {
 161              return;
 162          }
 163  
 164          if ($this->getHttpKernel() instanceof TerminableInterface) {
 165              $this->getHttpKernel()->terminate($request, $response);
 166          }
 167      }
 168  
 169      /**
 170       * {@inheritdoc}
 171       */
 172      public function shutdown()
 173      {
 174          if (false === $this->booted) {
 175              return;
 176          }
 177  
 178          $this->booted = false;
 179  
 180          foreach ($this->getBundles() as $bundle) {
 181              $bundle->shutdown();
 182              $bundle->setContainer(null);
 183          }
 184  
 185          $this->container = null;
 186          $this->requestStackSize = 0;
 187          $this->resetServices = false;
 188      }
 189  
 190      /**
 191       * {@inheritdoc}
 192       */
 193      public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true)
 194      {
 195          $this->boot();
 196          ++$this->requestStackSize;
 197          $this->resetServices = true;
 198  
 199          try {
 200              return $this->getHttpKernel()->handle($request, $type, $catch);
 201          } finally {
 202              --$this->requestStackSize;
 203          }
 204      }
 205  
 206      /**
 207       * Gets a HTTP kernel from the container.
 208       *
 209       * @return HttpKernelInterface
 210       */
 211      protected function getHttpKernel()
 212      {
 213          return $this->container->get('http_kernel');
 214      }
 215  
 216      /**
 217       * {@inheritdoc}
 218       */
 219      public function getBundles()
 220      {
 221          return $this->bundles;
 222      }
 223  
 224      /**
 225       * {@inheritdoc}
 226       */
 227      public function getBundle($name, $first = true/*, $noDeprecation = false */)
 228      {
 229          $noDeprecation = false;
 230          if (\func_num_args() >= 3) {
 231              $noDeprecation = func_get_arg(2);
 232          }
 233  
 234          if (!$first && !$noDeprecation) {
 235              @trigger_error(sprintf('Passing "false" as the second argument to "%s()" is deprecated as of 3.4 and will be removed in 4.0.', __METHOD__), \E_USER_DEPRECATED);
 236          }
 237  
 238          if (!isset($this->bundleMap[$name])) {
 239              throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the registerBundles() method of your "%s.php" file?', $name, static::class));
 240          }
 241  
 242          if (true === $first) {
 243              return $this->bundleMap[$name][0];
 244          }
 245  
 246          return $this->bundleMap[$name];
 247      }
 248  
 249      /**
 250       * {@inheritdoc}
 251       *
 252       * @throws \RuntimeException if a custom resource is hidden by a resource in a derived bundle
 253       */
 254      public function locateResource($name, $dir = null, $first = true)
 255      {
 256          if ('@' !== $name[0]) {
 257              throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name));
 258          }
 259  
 260          if (false !== strpos($name, '..')) {
 261              throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name));
 262          }
 263  
 264          $bundleName = substr($name, 1);
 265          $path = '';
 266          if (false !== strpos($bundleName, '/')) {
 267              list($bundleName, $path) = explode('/', $bundleName, 2);
 268          }
 269  
 270          $isResource = 0 === strpos($path, 'Resources') && null !== $dir;
 271          $overridePath = substr($path, 9);
 272          $resourceBundle = null;
 273          $bundles = $this->getBundle($bundleName, false, true);
 274          $files = [];
 275  
 276          foreach ($bundles as $bundle) {
 277              if ($isResource && file_exists($file = $dir.'/'.$bundle->getName().$overridePath)) {
 278                  if (null !== $resourceBundle) {
 279                      throw new \RuntimeException(sprintf('"%s" resource is hidden by a resource from the "%s" derived bundle. Create a "%s" file to override the bundle resource.', $file, $resourceBundle, $dir.'/'.$bundles[0]->getName().$overridePath));
 280                  }
 281  
 282                  if ($first) {
 283                      return $file;
 284                  }
 285                  $files[] = $file;
 286              }
 287  
 288              if (file_exists($file = $bundle->getPath().'/'.$path)) {
 289                  if ($first && !$isResource) {
 290                      return $file;
 291                  }
 292                  $files[] = $file;
 293                  $resourceBundle = $bundle->getName();
 294              }
 295          }
 296  
 297          if (\count($files) > 0) {
 298              return $first && $isResource ? $files[0] : $files;
 299          }
 300  
 301          throw new \InvalidArgumentException(sprintf('Unable to find file "%s".', $name));
 302      }
 303  
 304      /**
 305       * {@inheritdoc}
 306       */
 307      public function getName()
 308      {
 309          if (null === $this->name) {
 310              $this->name = preg_replace('/[^a-zA-Z0-9_]+/', '', basename($this->rootDir));
 311              if (ctype_digit($this->name[0])) {
 312                  $this->name = '_'.$this->name;
 313              }
 314          }
 315  
 316          return $this->name;
 317      }
 318  
 319      /**
 320       * {@inheritdoc}
 321       */
 322      public function getEnvironment()
 323      {
 324          return $this->environment;
 325      }
 326  
 327      /**
 328       * {@inheritdoc}
 329       */
 330      public function isDebug()
 331      {
 332          return $this->debug;
 333      }
 334  
 335      /**
 336       * {@inheritdoc}
 337       */
 338      public function getRootDir()
 339      {
 340          if (null === $this->rootDir) {
 341              $r = new \ReflectionObject($this);
 342              $this->rootDir = \dirname($r->getFileName());
 343          }
 344  
 345          return $this->rootDir;
 346      }
 347  
 348      /**
 349       * Gets the application root dir (path of the project's composer file).
 350       *
 351       * @return string The project root dir
 352       */
 353      public function getProjectDir()
 354      {
 355          if (null === $this->projectDir) {
 356              $r = new \ReflectionObject($this);
 357  
 358              if (!file_exists($dir = $r->getFileName())) {
 359                  throw new \LogicException(sprintf('Cannot auto-detect project dir for kernel of class "%s".', $r->name));
 360              }
 361  
 362              $dir = $rootDir = \dirname($dir);
 363              while (!file_exists($dir.'/composer.json')) {
 364                  if ($dir === \dirname($dir)) {
 365                      return $this->projectDir = $rootDir;
 366                  }
 367                  $dir = \dirname($dir);
 368              }
 369              $this->projectDir = $dir;
 370          }
 371  
 372          return $this->projectDir;
 373      }
 374  
 375      /**
 376       * {@inheritdoc}
 377       */
 378      public function getContainer()
 379      {
 380          return $this->container;
 381      }
 382  
 383      /**
 384       * Loads the PHP class cache.
 385       *
 386       * This methods only registers the fact that you want to load the cache classes.
 387       * The cache will actually only be loaded when the Kernel is booted.
 388       *
 389       * That optimization is mainly useful when using the HttpCache class in which
 390       * case the class cache is not loaded if the Response is in the cache.
 391       *
 392       * @param string $name      The cache name prefix
 393       * @param string $extension File extension of the resulting file
 394       *
 395       * @deprecated since version 3.3, to be removed in 4.0. The class cache is not needed anymore when using PHP 7.0.
 396       */
 397      public function loadClassCache($name = 'classes', $extension = '.php')
 398      {
 399          if (\PHP_VERSION_ID >= 70000) {
 400              @trigger_error(__METHOD__.'() is deprecated since Symfony 3.3, to be removed in 4.0.', \E_USER_DEPRECATED);
 401          }
 402  
 403          $this->loadClassCache = [$name, $extension];
 404      }
 405  
 406      /**
 407       * @internal
 408       *
 409       * @deprecated since version 3.3, to be removed in 4.0.
 410       */
 411      public function setClassCache(array $classes)
 412      {
 413          if (\PHP_VERSION_ID >= 70000) {
 414              @trigger_error(__METHOD__.'() is deprecated since Symfony 3.3, to be removed in 4.0.', \E_USER_DEPRECATED);
 415          }
 416  
 417          file_put_contents(($this->warmupDir ?: $this->getCacheDir()).'/classes.map', sprintf('<?php return %s;', var_export($classes, true)));
 418      }
 419  
 420      /**
 421       * @internal
 422       */
 423      public function setAnnotatedClassCache(array $annotatedClasses)
 424      {
 425          file_put_contents(($this->warmupDir ?: $this->getCacheDir()).'/annotations.map', sprintf('<?php return %s;', var_export($annotatedClasses, true)));
 426      }
 427  
 428      /**
 429       * {@inheritdoc}
 430       */
 431      public function getStartTime()
 432      {
 433          return $this->debug && null !== $this->startTime ? $this->startTime : -\INF;
 434      }
 435  
 436      /**
 437       * {@inheritdoc}
 438       */
 439      public function getCacheDir()
 440      {
 441          return $this->rootDir.'/cache/'.$this->environment;
 442      }
 443  
 444      /**
 445       * {@inheritdoc}
 446       */
 447      public function getLogDir()
 448      {
 449          return $this->rootDir.'/logs';
 450      }
 451  
 452      /**
 453       * {@inheritdoc}
 454       */
 455      public function getCharset()
 456      {
 457          return 'UTF-8';
 458      }
 459  
 460      /**
 461       * @deprecated since version 3.3, to be removed in 4.0.
 462       */
 463      protected function doLoadClassCache($name, $extension)
 464      {
 465          if (\PHP_VERSION_ID >= 70000) {
 466              @trigger_error(__METHOD__.'() is deprecated since Symfony 3.3, to be removed in 4.0.', \E_USER_DEPRECATED);
 467          }
 468          $cacheDir = $this->warmupDir ?: $this->getCacheDir();
 469  
 470          if (!$this->booted && is_file($cacheDir.'/classes.map')) {
 471              ClassCollectionLoader::load(include($cacheDir.'/classes.map'), $cacheDir, $name, $this->debug, false, $extension);
 472          }
 473      }
 474  
 475      /**
 476       * Initializes the data structures related to the bundle management.
 477       *
 478       *  - the bundles property maps a bundle name to the bundle instance,
 479       *  - the bundleMap property maps a bundle name to the bundle inheritance hierarchy (most derived bundle first).
 480       *
 481       * @throws \LogicException if two bundles share a common name
 482       * @throws \LogicException if a bundle tries to extend a non-registered bundle
 483       * @throws \LogicException if a bundle tries to extend itself
 484       * @throws \LogicException if two bundles extend the same ancestor
 485       */
 486      protected function initializeBundles()
 487      {
 488          // init bundles
 489          $this->bundles = [];
 490          $topMostBundles = [];
 491          $directChildren = [];
 492  
 493          foreach ($this->registerBundles() as $bundle) {
 494              $name = $bundle->getName();
 495              if (isset($this->bundles[$name])) {
 496                  throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s".', $name));
 497              }
 498              $this->bundles[$name] = $bundle;
 499  
 500              if ($parentName = $bundle->getParent()) {
 501                  @trigger_error('Bundle inheritance is deprecated as of 3.4 and will be removed in 4.0.', \E_USER_DEPRECATED);
 502  
 503                  if (isset($directChildren[$parentName])) {
 504                      throw new \LogicException(sprintf('Bundle "%s" is directly extended by two bundles "%s" and "%s".', $parentName, $name, $directChildren[$parentName]));
 505                  }
 506                  if ($parentName == $name) {
 507                      throw new \LogicException(sprintf('Bundle "%s" can not extend itself.', $name));
 508                  }
 509                  $directChildren[$parentName] = $name;
 510              } else {
 511                  $topMostBundles[$name] = $bundle;
 512              }
 513          }
 514  
 515          // look for orphans
 516          if (!empty($directChildren) && \count($diff = array_diff_key($directChildren, $this->bundles))) {
 517              $diff = array_keys($diff);
 518  
 519              throw new \LogicException(sprintf('Bundle "%s" extends bundle "%s", which is not registered.', $directChildren[$diff[0]], $diff[0]));
 520          }
 521  
 522          // inheritance
 523          $this->bundleMap = [];
 524          foreach ($topMostBundles as $name => $bundle) {
 525              $bundleMap = [$bundle];
 526              $hierarchy = [$name];
 527  
 528              while (isset($directChildren[$name])) {
 529                  $name = $directChildren[$name];
 530                  array_unshift($bundleMap, $this->bundles[$name]);
 531                  $hierarchy[] = $name;
 532              }
 533  
 534              foreach ($hierarchy as $hierarchyBundle) {
 535                  $this->bundleMap[$hierarchyBundle] = $bundleMap;
 536                  array_pop($bundleMap);
 537              }
 538          }
 539      }
 540  
 541      /**
 542       * The extension point similar to the Bundle::build() method.
 543       *
 544       * Use this method to register compiler passes and manipulate the container during the building process.
 545       */
 546      protected function build(ContainerBuilder $container)
 547      {
 548      }
 549  
 550      /**
 551       * Gets the container class.
 552       *
 553       * @return string The container class
 554       */
 555      protected function getContainerClass()
 556      {
 557          return $this->name.ucfirst($this->environment).($this->debug ? 'Debug' : '').'ProjectContainer';
 558      }
 559  
 560      /**
 561       * Gets the container's base class.
 562       *
 563       * All names except Container must be fully qualified.
 564       *
 565       * @return string
 566       */
 567      protected function getContainerBaseClass()
 568      {
 569          return 'Container';
 570      }
 571  
 572      /**
 573       * Initializes the service container.
 574       *
 575       * The cached version of the service container is used when fresh, otherwise the
 576       * container is built.
 577       */
 578      protected function initializeContainer()
 579      {
 580          $class = $this->getContainerClass();
 581          $cacheDir = $this->warmupDir ?: $this->getCacheDir();
 582          $cache = new ConfigCache($cacheDir.'/'.$class.'.php', $this->debug);
 583          $oldContainer = null;
 584          if ($fresh = $cache->isFresh()) {
 585              // Silence E_WARNING to ignore "include" failures - don't use "@" to prevent silencing fatal errors
 586              $errorLevel = error_reporting(\E_ALL ^ \E_WARNING);
 587              $fresh = $oldContainer = false;
 588              try {
 589                  if (file_exists($cache->getPath()) && \is_object($this->container = include $cache->getPath())) {
 590                      $this->container->set('kernel', $this);
 591                      $oldContainer = $this->container;
 592                      $fresh = true;
 593                  }
 594              } catch (\Throwable $e) {
 595              } catch (\Exception $e) {
 596              } finally {
 597                  error_reporting($errorLevel);
 598              }
 599          }
 600  
 601          if ($fresh) {
 602              return;
 603          }
 604  
 605          if ($collectDeprecations = $this->debug && !\defined('PHPUNIT_COMPOSER_INSTALL')) {
 606              $collectedLogs = [];
 607              $previousHandler = set_error_handler(function ($type, $message, $file, $line) use (&$collectedLogs, &$previousHandler) {
 608                  if (\E_USER_DEPRECATED !== $type && \E_DEPRECATED !== $type) {
 609                      return $previousHandler ? $previousHandler($type, $message, $file, $line) : false;
 610                  }
 611  
 612                  if (isset($collectedLogs[$message])) {
 613                      ++$collectedLogs[$message]['count'];
 614  
 615                      return null;
 616                  }
 617  
 618                  $backtrace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 3);
 619                  // Clean the trace by removing first frames added by the error handler itself.
 620                  for ($i = 0; isset($backtrace[$i]); ++$i) {
 621                      if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) {
 622                          $backtrace = \array_slice($backtrace, 1 + $i);
 623                          break;
 624                      }
 625                  }
 626  
 627                  $collectedLogs[$message] = [
 628                      'type' => $type,
 629                      'message' => $message,
 630                      'file' => $file,
 631                      'line' => $line,
 632                      'trace' => $backtrace,
 633                      'count' => 1,
 634                  ];
 635  
 636                  return null;
 637              });
 638          }
 639  
 640          try {
 641              $container = null;
 642              $container = $this->buildContainer();
 643              $container->compile();
 644          } finally {
 645              if ($collectDeprecations) {
 646                  restore_error_handler();
 647  
 648                  file_put_contents($cacheDir.'/'.$class.'Deprecations.log', serialize(array_values($collectedLogs)));
 649                  file_put_contents($cacheDir.'/'.$class.'Compiler.log', null !== $container ? implode("\n", $container->getCompiler()->getLog()) : '');
 650              }
 651          }
 652  
 653          if (null === $oldContainer && file_exists($cache->getPath())) {
 654              $errorLevel = error_reporting(\E_ALL ^ \E_WARNING);
 655              try {
 656                  $oldContainer = include $cache->getPath();
 657              } catch (\Throwable $e) {
 658              } catch (\Exception $e) {
 659              } finally {
 660                  error_reporting($errorLevel);
 661              }
 662          }
 663          $oldContainer = \is_object($oldContainer) ? new \ReflectionClass($oldContainer) : false;
 664  
 665          $this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass());
 666          $this->container = require $cache->getPath();
 667          $this->container->set('kernel', $this);
 668  
 669          if ($oldContainer && \get_class($this->container) !== $oldContainer->name) {
 670              // Because concurrent requests might still be using them,
 671              // old container files are not removed immediately,
 672              // but on a next dump of the container.
 673              static $legacyContainers = [];
 674              $oldContainerDir = \dirname($oldContainer->getFileName());
 675              $legacyContainers[$oldContainerDir.'.legacy'] = true;
 676              foreach (glob(\dirname($oldContainerDir).\DIRECTORY_SEPARATOR.'*.legacy', \GLOB_NOSORT) as $legacyContainer) {
 677                  if (!isset($legacyContainers[$legacyContainer]) && @unlink($legacyContainer)) {
 678                      (new Filesystem())->remove(substr($legacyContainer, 0, -7));
 679                  }
 680              }
 681  
 682              touch($oldContainerDir.'.legacy');
 683          }
 684  
 685          if ($this->container->has('cache_warmer')) {
 686              $this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir'));
 687          }
 688      }
 689  
 690      /**
 691       * Returns the kernel parameters.
 692       *
 693       * @return array An array of kernel parameters
 694       */
 695      protected function getKernelParameters()
 696      {
 697          $bundles = [];
 698          $bundlesMetadata = [];
 699  
 700          foreach ($this->bundles as $name => $bundle) {
 701              $bundles[$name] = \get_class($bundle);
 702              $bundlesMetadata[$name] = [
 703                  'parent' => $bundle->getParent(),
 704                  'path' => $bundle->getPath(),
 705                  'namespace' => $bundle->getNamespace(),
 706              ];
 707          }
 708  
 709          return array_merge(
 710              [
 711                  'kernel.root_dir' => realpath($this->rootDir) ?: $this->rootDir,
 712                  'kernel.project_dir' => realpath($this->getProjectDir()) ?: $this->getProjectDir(),
 713                  'kernel.environment' => $this->environment,
 714                  'kernel.debug' => $this->debug,
 715                  'kernel.name' => $this->name,
 716                  'kernel.cache_dir' => realpath($cacheDir = $this->warmupDir ?: $this->getCacheDir()) ?: $cacheDir,
 717                  'kernel.logs_dir' => realpath($this->getLogDir()) ?: $this->getLogDir(),
 718                  'kernel.bundles' => $bundles,
 719                  'kernel.bundles_metadata' => $bundlesMetadata,
 720                  'kernel.charset' => $this->getCharset(),
 721                  'kernel.container_class' => $this->getContainerClass(),
 722              ],
 723              $this->getEnvParameters(false)
 724          );
 725      }
 726  
 727      /**
 728       * Gets the environment parameters.
 729       *
 730       * Only the parameters starting with "SYMFONY__" are considered.
 731       *
 732       * @return array An array of parameters
 733       *
 734       * @deprecated since version 3.3, to be removed in 4.0
 735       */
 736      protected function getEnvParameters()
 737      {
 738          if (0 === \func_num_args() || func_get_arg(0)) {
 739              @trigger_error(sprintf('The "%s()" method is deprecated as of 3.3 and will be removed in 4.0. Use the %%env()%% syntax to get the value of any environment variable from configuration files instead.', __METHOD__), \E_USER_DEPRECATED);
 740          }
 741  
 742          $parameters = [];
 743          foreach ($_SERVER as $key => $value) {
 744              if (0 === strpos($key, 'SYMFONY__')) {
 745                  @trigger_error(sprintf('The support of special environment variables that start with SYMFONY__ (such as "%s") is deprecated as of 3.3 and will be removed in 4.0. Use the %%env()%% syntax instead to get the value of environment variables in configuration files.', $key), \E_USER_DEPRECATED);
 746                  $parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value;
 747              }
 748          }
 749  
 750          return $parameters;
 751      }
 752  
 753      /**
 754       * Builds the service container.
 755       *
 756       * @return ContainerBuilder The compiled service container
 757       *
 758       * @throws \RuntimeException
 759       */
 760      protected function buildContainer()
 761      {
 762          foreach (['cache' => $this->warmupDir ?: $this->getCacheDir(), 'logs' => $this->getLogDir()] as $name => $dir) {
 763              if (!is_dir($dir)) {
 764                  if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) {
 765                      throw new \RuntimeException(sprintf('Unable to create the "%s" directory (%s).', $name, $dir));
 766                  }
 767              } elseif (!is_writable($dir)) {
 768                  throw new \RuntimeException(sprintf('Unable to write in the "%s" directory (%s).', $name, $dir));
 769              }
 770          }
 771  
 772          $container = $this->getContainerBuilder();
 773          $container->addObjectResource($this);
 774          $this->prepareContainer($container);
 775  
 776          if (null !== $cont = $this->registerContainerConfiguration($this->getContainerLoader($container))) {
 777              $container->merge($cont);
 778          }
 779  
 780          $container->addCompilerPass(new AddAnnotatedClassesToCachePass($this));
 781          $container->addResource(new EnvParametersResource('SYMFONY__'));
 782  
 783          return $container;
 784      }
 785  
 786      /**
 787       * Prepares the ContainerBuilder before it is compiled.
 788       */
 789      protected function prepareContainer(ContainerBuilder $container)
 790      {
 791          $extensions = [];
 792          foreach ($this->bundles as $bundle) {
 793              if ($extension = $bundle->getContainerExtension()) {
 794                  $container->registerExtension($extension);
 795              }
 796  
 797              if ($this->debug) {
 798                  $container->addObjectResource($bundle);
 799              }
 800          }
 801  
 802          foreach ($this->bundles as $bundle) {
 803              $bundle->build($container);
 804          }
 805  
 806          $this->build($container);
 807  
 808          foreach ($container->getExtensions() as $extension) {
 809              $extensions[] = $extension->getAlias();
 810          }
 811  
 812          // ensure these extensions are implicitly loaded
 813          $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions));
 814      }
 815  
 816      /**
 817       * Gets a new ContainerBuilder instance used to build the service container.
 818       *
 819       * @return ContainerBuilder
 820       */
 821      protected function getContainerBuilder()
 822      {
 823          $container = new ContainerBuilder();
 824          $container->getParameterBag()->add($this->getKernelParameters());
 825  
 826          if ($this instanceof CompilerPassInterface) {
 827              $container->addCompilerPass($this, PassConfig::TYPE_BEFORE_OPTIMIZATION, -10000);
 828          }
 829          if (class_exists('ProxyManager\Configuration') && class_exists('Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator')) {
 830              $container->setProxyInstantiator(new RuntimeInstantiator());
 831          }
 832  
 833          return $container;
 834      }
 835  
 836      /**
 837       * Dumps the service container to PHP code in the cache.
 838       *
 839       * @param ConfigCache      $cache     The config cache
 840       * @param ContainerBuilder $container The service container
 841       * @param string           $class     The name of the class to generate
 842       * @param string           $baseClass The name of the container's base class
 843       */
 844      protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, $class, $baseClass)
 845      {
 846          // cache the container
 847          $dumper = new PhpDumper($container);
 848  
 849          if (class_exists('ProxyManager\Configuration') && class_exists('Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper')) {
 850              $dumper->setProxyDumper(new ProxyDumper());
 851          }
 852  
 853          $content = $dumper->dump([
 854              'class' => $class,
 855              'base_class' => $baseClass,
 856              'file' => $cache->getPath(),
 857              'as_files' => true,
 858              'debug' => $this->debug,
 859              'inline_class_loader_parameter' => \PHP_VERSION_ID >= 70000 && !$this->loadClassCache && !class_exists(ClassCollectionLoader::class, false) ? 'container.dumper.inline_class_loader' : null,
 860              'build_time' => $container->hasParameter('kernel.container_build_time') ? $container->getParameter('kernel.container_build_time') : time(),
 861          ]);
 862  
 863          $rootCode = array_pop($content);
 864          $dir = \dirname($cache->getPath()).'/';
 865          $fs = new Filesystem();
 866  
 867          foreach ($content as $file => $code) {
 868              $fs->dumpFile($dir.$file, $code);
 869              @chmod($dir.$file, 0666 & ~umask());
 870          }
 871          $legacyFile = \dirname($dir.key($content)).'.legacy';
 872          if (file_exists($legacyFile)) {
 873              @unlink($legacyFile);
 874          }
 875  
 876          $cache->write($rootCode, $container->getResources());
 877      }
 878  
 879      /**
 880       * Returns a loader for the container.
 881       *
 882       * @return DelegatingLoader The loader
 883       */
 884      protected function getContainerLoader(ContainerInterface $container)
 885      {
 886          $locator = new FileLocator($this);
 887          $resolver = new LoaderResolver([
 888              new XmlFileLoader($container, $locator),
 889              new YamlFileLoader($container, $locator),
 890              new IniFileLoader($container, $locator),
 891              new PhpFileLoader($container, $locator),
 892              new GlobFileLoader($container, $locator),
 893              new DirectoryLoader($container, $locator),
 894              new ClosureLoader($container),
 895          ]);
 896  
 897          return new DelegatingLoader($resolver);
 898      }
 899  
 900      /**
 901       * Removes comments from a PHP source string.
 902       *
 903       * We don't use the PHP php_strip_whitespace() function
 904       * as we want the content to be readable and well-formatted.
 905       *
 906       * @param string $source A PHP string
 907       *
 908       * @return string The PHP string with the comments removed
 909       */
 910      public static function stripComments($source)
 911      {
 912          if (!\function_exists('token_get_all')) {
 913              return $source;
 914          }
 915  
 916          $rawChunk = '';
 917          $output = '';
 918          $tokens = token_get_all($source);
 919          $ignoreSpace = false;
 920          for ($i = 0; isset($tokens[$i]); ++$i) {
 921              $token = $tokens[$i];
 922              if (!isset($token[1]) || 'b"' === $token) {
 923                  $rawChunk .= $token;
 924              } elseif (\T_START_HEREDOC === $token[0]) {
 925                  $output .= $rawChunk.$token[1];
 926                  do {
 927                      $token = $tokens[++$i];
 928                      $output .= isset($token[1]) && 'b"' !== $token ? $token[1] : $token;
 929                  } while (\T_END_HEREDOC !== $token[0]);
 930                  $rawChunk = '';
 931              } elseif (\T_WHITESPACE === $token[0]) {
 932                  if ($ignoreSpace) {
 933                      $ignoreSpace = false;
 934  
 935                      continue;
 936                  }
 937  
 938                  // replace multiple new lines with a single newline
 939                  $rawChunk .= preg_replace(['/\n{2,}/S'], "\n", $token[1]);
 940              } elseif (\in_array($token[0], [\T_COMMENT, \T_DOC_COMMENT])) {
 941                  $ignoreSpace = true;
 942              } else {
 943                  $rawChunk .= $token[1];
 944  
 945                  // The PHP-open tag already has a new-line
 946                  if (\T_OPEN_TAG === $token[0]) {
 947                      $ignoreSpace = true;
 948                  }
 949              }
 950          }
 951  
 952          $output .= $rawChunk;
 953  
 954          if (\PHP_VERSION_ID >= 70000) {
 955              // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098
 956              unset($tokens, $rawChunk);
 957              gc_mem_caches();
 958          }
 959  
 960          return $output;
 961      }
 962  
 963      public function serialize()
 964      {
 965          return serialize([$this->environment, $this->debug]);
 966      }
 967  
 968      public function unserialize($data)
 969      {
 970          if (\PHP_VERSION_ID >= 70000) {
 971              list($environment, $debug) = unserialize($data, ['allowed_classes' => false]);
 972          } else {
 973              list($environment, $debug) = unserialize($data);
 974          }
 975  
 976          $this->__construct($environment, $debug);
 977      }
 978  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1