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

UrlMatcher.php

Zuletzt modifiziert: 01.05.2026, 11:27 - Dateigröße: 8.97 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\Routing\Matcher;
 013   
 014  use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
 015  use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
 016  use Symfony\Component\HttpFoundation\Request;
 017  use Symfony\Component\Routing\Exception\MethodNotAllowedException;
 018  use Symfony\Component\Routing\Exception\NoConfigurationException;
 019  use Symfony\Component\Routing\Exception\ResourceNotFoundException;
 020  use Symfony\Component\Routing\RequestContext;
 021  use Symfony\Component\Routing\Route;
 022  use Symfony\Component\Routing\RouteCollection;
 023   
 024  /**
 025   * UrlMatcher matches URL based on a set of routes.
 026   *
 027   * @author Fabien Potencier <fabien@symfony.com>
 028   */
 029  class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
 030  {
 031      const REQUIREMENT_MATCH = 0;
 032      const REQUIREMENT_MISMATCH = 1;
 033      const ROUTE_MATCH = 2;
 034   
 035      protected $context;
 036      protected $allow = [];
 037      protected $routes;
 038      protected $request;
 039      protected $expressionLanguage;
 040   
 041      /**
 042       * @var ExpressionFunctionProviderInterface[]
 043       */
 044      protected $expressionLanguageProviders = [];
 045   
 046      public function __construct(RouteCollection $routes, RequestContext $context)
 047      {
 048          $this->routes = $routes;
 049          $this->context = $context;
 050      }
 051   
 052      /**
 053       * {@inheritdoc}
 054       */
 055      public function setContext(RequestContext $context)
 056      {
 057          $this->context = $context;
 058      }
 059   
 060      /**
 061       * {@inheritdoc}
 062       */
 063      public function getContext()
 064      {
 065          return $this->context;
 066      }
 067   
 068      /**
 069       * {@inheritdoc}
 070       */
 071      public function match($pathinfo)
 072      {
 073          $this->allow = [];
 074   
 075          if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) {
 076              return $ret;
 077          }
 078   
 079          if ('/' === $pathinfo && !$this->allow) {
 080              throw new NoConfigurationException();
 081          }
 082   
 083          throw 0 < \count($this->allow) ? new MethodNotAllowedException(array_unique($this->allow)) : new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo));
 084      }
 085   
 086      /**
 087       * {@inheritdoc}
 088       */
 089      public function matchRequest(Request $request)
 090      {
 091          $this->request = $request;
 092   
 093          $ret = $this->match($request->getPathInfo());
 094   
 095          $this->request = null;
 096   
 097          return $ret;
 098      }
 099   
 100      public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider)
 101      {
 102          $this->expressionLanguageProviders[] = $provider;
 103      }
 104   
 105      /**
 106       * Tries to match a URL with a set of routes.
 107       *
 108       * @param string          $pathinfo The path info to be parsed
 109       * @param RouteCollection $routes   The set of routes
 110       *
 111       * @return array An array of parameters
 112       *
 113       * @throws NoConfigurationException  If no routing configuration could be found
 114       * @throws ResourceNotFoundException If the resource could not be found
 115       * @throws MethodNotAllowedException If the resource was found but the request method is not allowed
 116       */
 117      protected function matchCollection($pathinfo, RouteCollection $routes)
 118      {
 119          // HEAD and GET are equivalent as per RFC
 120          if ('HEAD' === $method = $this->context->getMethod()) {
 121              $method = 'GET';
 122          }
 123          $supportsTrailingSlash = '/' !== $pathinfo && '' !== $pathinfo && $this instanceof RedirectableUrlMatcherInterface;
 124   
 125          foreach ($routes as $name => $route) {
 126              $compiledRoute = $route->compile();
 127              $staticPrefix = $compiledRoute->getStaticPrefix();
 128              $requiredMethods = $route->getMethods();
 129   
 130              // check the static prefix of the URL first. Only use the more expensive preg_match when it matches
 131              if ('' === $staticPrefix || 0 === strpos($pathinfo, $staticPrefix)) {
 132                  // no-op
 133              } elseif (!$supportsTrailingSlash || ($requiredMethods && !\in_array('GET', $requiredMethods)) || 'GET' !== $method) {
 134                  continue;
 135              } elseif ('/' === substr($staticPrefix, -1) && substr($staticPrefix, 0, -1) === $pathinfo) {
 136                  return $this->allow = [];
 137              } else {
 138                  continue;
 139              }
 140              $regex = $compiledRoute->getRegex();
 141   
 142              if ($supportsTrailingSlash && $pos = strpos($regex, '/$')) {
 143                  $regex = substr($regex, 0, $pos).'/?$'.substr($regex, $pos + 2);
 144                  $hasTrailingSlash = true;
 145              } else {
 146                  $hasTrailingSlash = false;
 147              }
 148   
 149              if (!preg_match($regex, $pathinfo, $matches)) {
 150                  continue;
 151              }
 152   
 153              if ($hasTrailingSlash && '/' !== substr($pathinfo, -1)) {
 154                  if ((!$requiredMethods || \in_array('GET', $requiredMethods)) && 'GET' === $method) {
 155                      return $this->allow = [];
 156                  }
 157                  continue;
 158              }
 159   
 160              $hostMatches = [];
 161              if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) {
 162                  continue;
 163              }
 164   
 165              $status = $this->handleRouteRequirements($pathinfo, $name, $route);
 166   
 167              if (self::REQUIREMENT_MISMATCH === $status[0]) {
 168                  continue;
 169              }
 170   
 171              // check HTTP method requirement
 172              if ($requiredMethods) {
 173                  if (!\in_array($method, $requiredMethods)) {
 174                      if (self::REQUIREMENT_MATCH === $status[0]) {
 175                          $this->allow = array_merge($this->allow, $requiredMethods);
 176                      }
 177   
 178                      continue;
 179                  }
 180              }
 181   
 182              return $this->getAttributes($route, $name, array_replace($matches, $hostMatches, isset($status[1]) ? $status[1] : []));
 183          }
 184   
 185          return [];
 186      }
 187   
 188      /**
 189       * Returns an array of values to use as request attributes.
 190       *
 191       * As this method requires the Route object, it is not available
 192       * in matchers that do not have access to the matched Route instance
 193       * (like the PHP and Apache matcher dumpers).
 194       *
 195       * @param Route  $route      The route we are matching against
 196       * @param string $name       The name of the route
 197       * @param array  $attributes An array of attributes from the matcher
 198       *
 199       * @return array An array of parameters
 200       */
 201      protected function getAttributes(Route $route, $name, array $attributes)
 202      {
 203          $attributes['_route'] = $name;
 204   
 205          return $this->mergeDefaults($attributes, $route->getDefaults());
 206      }
 207   
 208      /**
 209       * Handles specific route requirements.
 210       *
 211       * @param string $pathinfo The path
 212       * @param string $name     The route name
 213       * @param Route  $route    The route
 214       *
 215       * @return array The first element represents the status, the second contains additional information
 216       */
 217      protected function handleRouteRequirements($pathinfo, $name, Route $route)
 218      {
 219          // expression condition
 220          if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), ['context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)])) {
 221              return [self::REQUIREMENT_MISMATCH, null];
 222          }
 223   
 224          // check HTTP scheme requirement
 225          $scheme = $this->context->getScheme();
 226          $status = $route->getSchemes() && !$route->hasScheme($scheme) ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH;
 227   
 228          return [$status, null];
 229      }
 230   
 231      /**
 232       * Get merged default parameters.
 233       *
 234       * @param array $params   The parameters
 235       * @param array $defaults The defaults
 236       *
 237       * @return array Merged default parameters
 238       */
 239      protected function mergeDefaults($params, $defaults)
 240      {
 241          foreach ($params as $key => $value) {
 242              if (!\is_int($key)) {
 243                  $defaults[$key] = $value;
 244              }
 245          }
 246   
 247          return $defaults;
 248      }
 249   
 250      protected function getExpressionLanguage()
 251      {
 252          if (null === $this->expressionLanguage) {
 253              if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) {
 254                  throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
 255              }
 256              $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders);
 257          }
 258   
 259          return $this->expressionLanguage;
 260      }
 261   
 262      /**
 263       * @internal
 264       */
 265      protected function createRequest($pathinfo)
 266      {
 267          if (!class_exists('Symfony\Component\HttpFoundation\Request')) {
 268              return null;
 269          }
 270   
 271          return Request::create($this->context->getScheme().'://'.$this->context->getHost().$this->context->getBaseUrl().$pathinfo, $this->context->getMethod(), $this->context->getParameters(), [], [], [
 272              'SCRIPT_FILENAME' => $this->context->getBaseUrl(),
 273              'SCRIPT_NAME' => $this->context->getBaseUrl(),
 274          ]);
 275      }
 276  }
 277