* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Symfony\Component\Routing\Matcher; @trigger_error('The '.__NAMESPACE__.'\ApacheUrlMatcher class is deprecated since Symfony 2.5 and will be removed in 3.0. It\'s hard to replicate the behaviour of the PHP implementation and the performance gains are minimal.', E_USER_DEPRECATED); use Symfony\Component\Routing\Exception\MethodNotAllowedException; /** * ApacheUrlMatcher matches URL based on Apache mod_rewrite matching (see ApacheMatcherDumper). * * @deprecated since version 2.5, to be removed in 3.0. * The performance gains are minimal and it's very hard to replicate * the behavior of PHP implementation. * * @author Fabien Potencier * @author Arnaud Le Blanc */ class ApacheUrlMatcher extends UrlMatcher { /** * Tries to match a URL based on Apache mod_rewrite matching. * * Returns false if no route matches the URL. * * @param string $pathinfo The pathinfo to be parsed * * @return array An array of parameters * * @throws MethodNotAllowedException If the current method is not allowed */ public function match($pathinfo) { $parameters = array(); $defaults = array(); $allow = array(); $route = null; foreach ($this->denormalizeValues($_SERVER) as $key => $value) { $name = $key; // skip non-routing variables // this improves performance when $_SERVER contains many usual // variables like HTTP_*, DOCUMENT_ROOT, REQUEST_URI, ... if (false === strpos($name, '_ROUTING_')) { continue; } while (0 === strpos($name, 'REDIRECT_')) { $name = substr($name, 9); } // expect _ROUTING__ // or _ROUTING_ if (0 !== strpos($name, '_ROUTING_')) { continue; } if (false !== $pos = strpos($name, '_', 9)) { $type = substr($name, 9, $pos - 9); $name = substr($name, $pos + 1); } else { $type = substr($name, 9); } if ('param' === $type) { if ('' !== $value) { $parameters[$name] = $value; } } elseif ('default' === $type) { $defaults[$name] = $value; } elseif ('route' === $type) { $route = $value; } elseif ('allow' === $type) { $allow[] = $name; } unset($_SERVER[$key]); } if (null !== $route) { $parameters['_route'] = $route; return $this->mergeDefaults($parameters, $defaults); } elseif (0 < \count($allow)) { throw new MethodNotAllowedException($allow); } else { return parent::match($pathinfo); } } /** * Denormalizes an array of values. * * @param string[] $values * * @return array */ private function denormalizeValues(array $values) { $normalizedValues = array(); foreach ($values as $key => $value) { if (preg_match('~^(.*)\[(\d+)\]$~', $key, $matches)) { if (!isset($normalizedValues[$matches[1]])) { $normalizedValues[$matches[1]] = array(); } $normalizedValues[$matches[1]][(int) $matches[2]] = $value; } else { $normalizedValues[$key] = $value; } } return $normalizedValues; } }