feature #21755 [Routing] Optimised dumped router matcher, prevent unneeded function calls. (frankdejonge)
This PR was squashed before being merged into the 3.3-dev branch (closes #21755).
Discussion
----------
[Routing] Optimised dumped router matcher, prevent unneeded function calls.
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | no
| Tests pass? | yes
| Fixed tickets | none
| License | MIT
| Doc PR | does not apply
The application I'm working on is fairly large. Because we had a routing issue (not caused by the framework) I looked through the dumped routing code. I spotted some easy wins. These changes brought down the time for the `match` method to run from ~ 7.5ms to ~2.5ms. It's not a lot, but it's something. I've profiled it several times with blackfire to confirm. The results were very consistent. Mind you, our application has quite a serious amount of routes, a little over 900.
Commits
-------
dd647ffc8a
[Routing] Optimised dumped router matcher, prevent unneeded function calls.
This commit is contained in:
commit
9e1b567d62
@ -105,8 +105,16 @@ EOF;
|
||||
{
|
||||
\$allow = array();
|
||||
\$pathinfo = rawurldecode(\$pathinfo);
|
||||
\$trimmedPathinfo = rtrim(\$pathinfo, '/');
|
||||
\$context = \$this->context;
|
||||
\$request = \$this->request;
|
||||
\$requestMethod = \$canonicalMethod = \$context->getMethod();
|
||||
\$scheme = \$context->getScheme();
|
||||
|
||||
if ('HEAD' === \$requestMethod) {
|
||||
\$canonicalMethod = 'GET';
|
||||
}
|
||||
|
||||
|
||||
$code
|
||||
|
||||
@ -133,7 +141,7 @@ EOF;
|
||||
foreach ($groups as $collection) {
|
||||
if (null !== $regex = $collection->getAttribute('host_regex')) {
|
||||
if (!$fetchedHost) {
|
||||
$code .= " \$host = \$this->context->getHost();\n\n";
|
||||
$code .= " \$host = \$context->getHost();\n\n";
|
||||
$fetchedHost = true;
|
||||
}
|
||||
|
||||
@ -217,20 +225,15 @@ EOF;
|
||||
$hostMatches = false;
|
||||
$methods = $route->getMethods();
|
||||
|
||||
// GET and HEAD are equivalent
|
||||
if (in_array('GET', $methods) && !in_array('HEAD', $methods)) {
|
||||
$methods[] = 'HEAD';
|
||||
}
|
||||
|
||||
$supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('HEAD', $methods));
|
||||
$regex = $compiledRoute->getRegex();
|
||||
|
||||
if (!count($compiledRoute->getPathVariables()) && false !== preg_match('#^(.)\^(?P<url>.*?)\$\1#'.(substr($regex, -1) === 'u' ? 'u' : ''), $regex, $m)) {
|
||||
if ($supportsTrailingSlash && substr($m['url'], -1) === '/') {
|
||||
$conditions[] = sprintf("rtrim(\$pathinfo, '/') === %s", var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true));
|
||||
$conditions[] = sprintf('%s === $trimmedPathinfo', var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true));
|
||||
$hasTrailingSlash = true;
|
||||
} else {
|
||||
$conditions[] = sprintf('$pathinfo === %s', var_export(str_replace('\\', '', $m['url']), true));
|
||||
$conditions[] = sprintf('%s === $pathinfo', var_export(str_replace('\\', '', $m['url']), true));
|
||||
}
|
||||
} else {
|
||||
if ($compiledRoute->getStaticPrefix() && $compiledRoute->getStaticPrefix() !== $parentPrefix) {
|
||||
@ -263,26 +266,57 @@ EOF;
|
||||
EOF;
|
||||
|
||||
$gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name);
|
||||
|
||||
if ($methods) {
|
||||
if (1 === count($methods)) {
|
||||
$code .= <<<EOF
|
||||
if (\$this->context->getMethod() != '$methods[0]') {
|
||||
if ($methods[0] === 'HEAD') {
|
||||
$code .= <<<EOF
|
||||
if ('HEAD' !== \$requestMethod) {
|
||||
\$allow[] = 'HEAD';
|
||||
goto $gotoname;
|
||||
}
|
||||
|
||||
|
||||
EOF;
|
||||
} else {
|
||||
$code .= <<<EOF
|
||||
if ('$methods[0]' !== \$canonicalMethod) {
|
||||
\$allow[] = '$methods[0]';
|
||||
goto $gotoname;
|
||||
}
|
||||
|
||||
|
||||
EOF;
|
||||
}
|
||||
} else {
|
||||
$methods = implode("', '", $methods);
|
||||
$code .= <<<EOF
|
||||
if (!in_array(\$this->context->getMethod(), array('$methods'))) {
|
||||
$methodVariable = 'requestMethod';
|
||||
|
||||
if (in_array('GET', $methods)) {
|
||||
// Since we treat HEAD requests like GET requests we don't need to match it.
|
||||
$methodVariable = 'canonicalMethod';
|
||||
$methods = array_filter($methods, function ($method) { return 'HEAD' !== $method; });
|
||||
}
|
||||
|
||||
if (1 === count($methods)) {
|
||||
$code .= <<<EOF
|
||||
if ('$methods[0]' !== \$$methodVariable) {
|
||||
\$allow[] = '$methods[0]';
|
||||
goto $gotoname;
|
||||
}
|
||||
|
||||
|
||||
EOF;
|
||||
} else {
|
||||
$methods = implode("', '", $methods);
|
||||
$code .= <<<EOF
|
||||
if (!in_array(\$$methodVariable, array('$methods'))) {
|
||||
\$allow = array_merge(\$allow, array('$methods'));
|
||||
goto $gotoname;
|
||||
}
|
||||
|
||||
|
||||
EOF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -303,7 +337,7 @@ EOF;
|
||||
$schemes = str_replace("\n", '', var_export(array_flip($schemes), true));
|
||||
$code .= <<<EOF
|
||||
\$requiredSchemes = $schemes;
|
||||
if (!isset(\$requiredSchemes[\$this->context->getScheme()])) {
|
||||
if (!isset(\$requiredSchemes[\$scheme])) {
|
||||
return \$this->redirect(\$pathinfo, '$name', key(\$requiredSchemes));
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,16 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
{
|
||||
$allow = array();
|
||||
$pathinfo = rawurldecode($pathinfo);
|
||||
$trimmedPathinfo = rtrim($pathinfo, '/');
|
||||
$context = $this->context;
|
||||
$request = $this->request;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
$scheme = $context->getScheme();
|
||||
|
||||
if ('HEAD' === $requestMethod) {
|
||||
$canonicalMethod = 'GET';
|
||||
}
|
||||
|
||||
|
||||
// foo
|
||||
if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?P<bar>baz|symfony)$#s', $pathinfo, $matches)) {
|
||||
@ -35,8 +43,8 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
if (0 === strpos($pathinfo, '/bar')) {
|
||||
// bar
|
||||
if (preg_match('#^/bar/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
|
||||
if (!in_array($this->context->getMethod(), array('GET', 'HEAD'))) {
|
||||
$allow = array_merge($allow, array('GET', 'HEAD'));
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
$allow[] = 'GET';
|
||||
goto not_bar;
|
||||
}
|
||||
|
||||
@ -46,8 +54,8 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
// barhead
|
||||
if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
|
||||
if (!in_array($this->context->getMethod(), array('GET', 'HEAD'))) {
|
||||
$allow = array_merge($allow, array('GET', 'HEAD'));
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
$allow[] = 'GET';
|
||||
goto not_barhead;
|
||||
}
|
||||
|
||||
@ -60,17 +68,17 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
if (0 === strpos($pathinfo, '/test')) {
|
||||
if (0 === strpos($pathinfo, '/test/baz')) {
|
||||
// baz
|
||||
if ($pathinfo === '/test/baz') {
|
||||
if ('/test/baz' === $pathinfo) {
|
||||
return array('_route' => 'baz');
|
||||
}
|
||||
|
||||
// baz2
|
||||
if ($pathinfo === '/test/baz.html') {
|
||||
if ('/test/baz.html' === $pathinfo) {
|
||||
return array('_route' => 'baz2');
|
||||
}
|
||||
|
||||
// baz3
|
||||
if ($pathinfo === '/test/baz3/') {
|
||||
if ('/test/baz3/' === $pathinfo) {
|
||||
return array('_route' => 'baz3');
|
||||
}
|
||||
|
||||
@ -83,7 +91,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
// baz5
|
||||
if (preg_match('#^/test/(?P<foo>[^/]++)/$#s', $pathinfo, $matches)) {
|
||||
if ($this->context->getMethod() != 'POST') {
|
||||
if ('POST' !== $canonicalMethod) {
|
||||
$allow[] = 'POST';
|
||||
goto not_baz5;
|
||||
}
|
||||
@ -94,7 +102,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
// baz.baz6
|
||||
if (preg_match('#^/test/(?P<foo>[^/]++)/$#s', $pathinfo, $matches)) {
|
||||
if ($this->context->getMethod() != 'PUT') {
|
||||
if ('PUT' !== $canonicalMethod) {
|
||||
$allow[] = 'PUT';
|
||||
goto not_bazbaz6;
|
||||
}
|
||||
@ -106,7 +114,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
|
||||
// foofoo
|
||||
if ($pathinfo === '/foofoo') {
|
||||
if ('/foofoo' === $pathinfo) {
|
||||
return array ( 'def' => 'test', '_route' => 'foofoo',);
|
||||
}
|
||||
|
||||
@ -116,7 +124,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
|
||||
// space
|
||||
if ($pathinfo === '/spa ce') {
|
||||
if ('/spa ce' === $pathinfo) {
|
||||
return array('_route' => 'space');
|
||||
}
|
||||
|
||||
@ -161,12 +169,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
|
||||
// overridden2
|
||||
if ($pathinfo === '/multi/new') {
|
||||
if ('/multi/new' === $pathinfo) {
|
||||
return array('_route' => 'overridden2');
|
||||
}
|
||||
|
||||
// hey
|
||||
if ($pathinfo === '/multi/hey/') {
|
||||
if ('/multi/hey/' === $pathinfo) {
|
||||
return array('_route' => 'hey');
|
||||
}
|
||||
|
||||
@ -184,7 +192,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
if (0 === strpos($pathinfo, '/aba')) {
|
||||
// ababa
|
||||
if ($pathinfo === '/ababa') {
|
||||
if ('/ababa' === $pathinfo) {
|
||||
return array('_route' => 'ababa');
|
||||
}
|
||||
|
||||
@ -195,16 +203,16 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
}
|
||||
|
||||
$host = $this->context->getHost();
|
||||
$host = $context->getHost();
|
||||
|
||||
if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) {
|
||||
// route1
|
||||
if ($pathinfo === '/route1') {
|
||||
if ('/route1' === $pathinfo) {
|
||||
return array('_route' => 'route1');
|
||||
}
|
||||
|
||||
// route2
|
||||
if ($pathinfo === '/c2/route2') {
|
||||
if ('/c2/route2' === $pathinfo) {
|
||||
return array('_route' => 'route2');
|
||||
}
|
||||
|
||||
@ -212,7 +220,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
if (preg_match('#^b\\.example\\.com$#si', $host, $hostMatches)) {
|
||||
// route3
|
||||
if ($pathinfo === '/c2/route3') {
|
||||
if ('/c2/route3' === $pathinfo) {
|
||||
return array('_route' => 'route3');
|
||||
}
|
||||
|
||||
@ -220,7 +228,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) {
|
||||
// route4
|
||||
if ($pathinfo === '/route4') {
|
||||
if ('/route4' === $pathinfo) {
|
||||
return array('_route' => 'route4');
|
||||
}
|
||||
|
||||
@ -228,26 +236,26 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
if (preg_match('#^c\\.example\\.com$#si', $host, $hostMatches)) {
|
||||
// route5
|
||||
if ($pathinfo === '/route5') {
|
||||
if ('/route5' === $pathinfo) {
|
||||
return array('_route' => 'route5');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// route6
|
||||
if ($pathinfo === '/route6') {
|
||||
if ('/route6' === $pathinfo) {
|
||||
return array('_route' => 'route6');
|
||||
}
|
||||
|
||||
if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#si', $host, $hostMatches)) {
|
||||
if (0 === strpos($pathinfo, '/route1')) {
|
||||
// route11
|
||||
if ($pathinfo === '/route11') {
|
||||
if ('/route11' === $pathinfo) {
|
||||
return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route11')), array ());
|
||||
}
|
||||
|
||||
// route12
|
||||
if ($pathinfo === '/route12') {
|
||||
if ('/route12' === $pathinfo) {
|
||||
return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route12')), array ( 'var1' => 'val',));
|
||||
}
|
||||
|
||||
@ -280,7 +288,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
|
||||
// route17
|
||||
if ($pathinfo === '/route17') {
|
||||
if ('/route17' === $pathinfo) {
|
||||
return array('_route' => 'route17');
|
||||
}
|
||||
|
||||
@ -288,7 +296,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
|
||||
if (0 === strpos($pathinfo, '/a')) {
|
||||
// a
|
||||
if ($pathinfo === '/a/a...') {
|
||||
if ('/a/a...' === $pathinfo) {
|
||||
return array('_route' => 'a');
|
||||
}
|
||||
|
||||
|
@ -24,8 +24,16 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
{
|
||||
$allow = array();
|
||||
$pathinfo = rawurldecode($pathinfo);
|
||||
$trimmedPathinfo = rtrim($pathinfo, '/');
|
||||
$context = $this->context;
|
||||
$request = $this->request;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
$scheme = $context->getScheme();
|
||||
|
||||
if ('HEAD' === $requestMethod) {
|
||||
$canonicalMethod = 'GET';
|
||||
}
|
||||
|
||||
|
||||
// foo
|
||||
if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?P<bar>baz|symfony)$#s', $pathinfo, $matches)) {
|
||||
@ -35,8 +43,8 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
if (0 === strpos($pathinfo, '/bar')) {
|
||||
// bar
|
||||
if (preg_match('#^/bar/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
|
||||
if (!in_array($this->context->getMethod(), array('GET', 'HEAD'))) {
|
||||
$allow = array_merge($allow, array('GET', 'HEAD'));
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
$allow[] = 'GET';
|
||||
goto not_bar;
|
||||
}
|
||||
|
||||
@ -46,8 +54,8 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
|
||||
// barhead
|
||||
if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?P<foo>[^/]++)$#s', $pathinfo, $matches)) {
|
||||
if (!in_array($this->context->getMethod(), array('GET', 'HEAD'))) {
|
||||
$allow = array_merge($allow, array('GET', 'HEAD'));
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
$allow[] = 'GET';
|
||||
goto not_barhead;
|
||||
}
|
||||
|
||||
@ -60,17 +68,17 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
if (0 === strpos($pathinfo, '/test')) {
|
||||
if (0 === strpos($pathinfo, '/test/baz')) {
|
||||
// baz
|
||||
if ($pathinfo === '/test/baz') {
|
||||
if ('/test/baz' === $pathinfo) {
|
||||
return array('_route' => 'baz');
|
||||
}
|
||||
|
||||
// baz2
|
||||
if ($pathinfo === '/test/baz.html') {
|
||||
if ('/test/baz.html' === $pathinfo) {
|
||||
return array('_route' => 'baz2');
|
||||
}
|
||||
|
||||
// baz3
|
||||
if (rtrim($pathinfo, '/') === '/test/baz3') {
|
||||
if ('/test/baz3' === $trimmedPathinfo) {
|
||||
if (substr($pathinfo, -1) !== '/') {
|
||||
return $this->redirect($pathinfo.'/', 'baz3');
|
||||
}
|
||||
@ -91,7 +99,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
|
||||
// baz5
|
||||
if (preg_match('#^/test/(?P<foo>[^/]++)/$#s', $pathinfo, $matches)) {
|
||||
if ($this->context->getMethod() != 'POST') {
|
||||
if ('POST' !== $canonicalMethod) {
|
||||
$allow[] = 'POST';
|
||||
goto not_baz5;
|
||||
}
|
||||
@ -102,7 +110,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
|
||||
// baz.baz6
|
||||
if (preg_match('#^/test/(?P<foo>[^/]++)/$#s', $pathinfo, $matches)) {
|
||||
if ($this->context->getMethod() != 'PUT') {
|
||||
if ('PUT' !== $canonicalMethod) {
|
||||
$allow[] = 'PUT';
|
||||
goto not_bazbaz6;
|
||||
}
|
||||
@ -114,7 +122,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
}
|
||||
|
||||
// foofoo
|
||||
if ($pathinfo === '/foofoo') {
|
||||
if ('/foofoo' === $pathinfo) {
|
||||
return array ( 'def' => 'test', '_route' => 'foofoo',);
|
||||
}
|
||||
|
||||
@ -124,7 +132,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
}
|
||||
|
||||
// space
|
||||
if ($pathinfo === '/spa ce') {
|
||||
if ('/spa ce' === $pathinfo) {
|
||||
return array('_route' => 'space');
|
||||
}
|
||||
|
||||
@ -169,12 +177,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
}
|
||||
|
||||
// overridden2
|
||||
if ($pathinfo === '/multi/new') {
|
||||
if ('/multi/new' === $pathinfo) {
|
||||
return array('_route' => 'overridden2');
|
||||
}
|
||||
|
||||
// hey
|
||||
if (rtrim($pathinfo, '/') === '/multi/hey') {
|
||||
if ('/multi/hey' === $trimmedPathinfo) {
|
||||
if (substr($pathinfo, -1) !== '/') {
|
||||
return $this->redirect($pathinfo.'/', 'hey');
|
||||
}
|
||||
@ -196,7 +204,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
|
||||
if (0 === strpos($pathinfo, '/aba')) {
|
||||
// ababa
|
||||
if ($pathinfo === '/ababa') {
|
||||
if ('/ababa' === $pathinfo) {
|
||||
return array('_route' => 'ababa');
|
||||
}
|
||||
|
||||
@ -207,16 +215,16 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
|
||||
}
|
||||
|
||||
$host = $this->context->getHost();
|
||||
$host = $context->getHost();
|
||||
|
||||
if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) {
|
||||
// route1
|
||||
if ($pathinfo === '/route1') {
|
||||
if ('/route1' === $pathinfo) {
|
||||
return array('_route' => 'route1');
|
||||
}
|
||||
|
||||
// route2
|
||||
if ($pathinfo === '/c2/route2') {
|
||||
if ('/c2/route2' === $pathinfo) {
|
||||
return array('_route' => 'route2');
|
||||
}
|
||||
|
||||
@ -224,7 +232,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
|
||||
if (preg_match('#^b\\.example\\.com$#si', $host, $hostMatches)) {
|
||||
// route3
|
||||
if ($pathinfo === '/c2/route3') {
|
||||
if ('/c2/route3' === $pathinfo) {
|
||||
return array('_route' => 'route3');
|
||||
}
|
||||
|
||||
@ -232,7 +240,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
|
||||
if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) {
|
||||
// route4
|
||||
if ($pathinfo === '/route4') {
|
||||
if ('/route4' === $pathinfo) {
|
||||
return array('_route' => 'route4');
|
||||
}
|
||||
|
||||
@ -240,26 +248,26 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
|
||||
if (preg_match('#^c\\.example\\.com$#si', $host, $hostMatches)) {
|
||||
// route5
|
||||
if ($pathinfo === '/route5') {
|
||||
if ('/route5' === $pathinfo) {
|
||||
return array('_route' => 'route5');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// route6
|
||||
if ($pathinfo === '/route6') {
|
||||
if ('/route6' === $pathinfo) {
|
||||
return array('_route' => 'route6');
|
||||
}
|
||||
|
||||
if (preg_match('#^(?P<var1>[^\\.]++)\\.example\\.com$#si', $host, $hostMatches)) {
|
||||
if (0 === strpos($pathinfo, '/route1')) {
|
||||
// route11
|
||||
if ($pathinfo === '/route11') {
|
||||
if ('/route11' === $pathinfo) {
|
||||
return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route11')), array ());
|
||||
}
|
||||
|
||||
// route12
|
||||
if ($pathinfo === '/route12') {
|
||||
if ('/route12' === $pathinfo) {
|
||||
return $this->mergeDefaults(array_replace($hostMatches, array('_route' => 'route12')), array ( 'var1' => 'val',));
|
||||
}
|
||||
|
||||
@ -292,7 +300,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
}
|
||||
|
||||
// route17
|
||||
if ($pathinfo === '/route17') {
|
||||
if ('/route17' === $pathinfo) {
|
||||
return array('_route' => 'route17');
|
||||
}
|
||||
|
||||
@ -300,7 +308,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
|
||||
if (0 === strpos($pathinfo, '/a')) {
|
||||
// a
|
||||
if ($pathinfo === '/a/a...') {
|
||||
if ('/a/a...' === $pathinfo) {
|
||||
return array('_route' => 'a');
|
||||
}
|
||||
|
||||
@ -320,9 +328,9 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
}
|
||||
|
||||
// secure
|
||||
if ($pathinfo === '/secure') {
|
||||
if ('/secure' === $pathinfo) {
|
||||
$requiredSchemes = array ( 'https' => 0,);
|
||||
if (!isset($requiredSchemes[$this->context->getScheme()])) {
|
||||
if (!isset($requiredSchemes[$scheme])) {
|
||||
return $this->redirect($pathinfo, 'secure', key($requiredSchemes));
|
||||
}
|
||||
|
||||
@ -330,9 +338,9 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
|
||||
}
|
||||
|
||||
// nonsecure
|
||||
if ($pathinfo === '/nonsecure') {
|
||||
if ('/nonsecure' === $pathinfo) {
|
||||
$requiredSchemes = array ( 'http' => 0,);
|
||||
if (!isset($requiredSchemes[$this->context->getScheme()])) {
|
||||
if (!isset($requiredSchemes[$scheme])) {
|
||||
return $this->redirect($pathinfo, 'nonsecure', key($requiredSchemes));
|
||||
}
|
||||
|
||||
|
@ -24,12 +24,20 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
{
|
||||
$allow = array();
|
||||
$pathinfo = rawurldecode($pathinfo);
|
||||
$trimmedPathinfo = rtrim($pathinfo, '/');
|
||||
$context = $this->context;
|
||||
$request = $this->request;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
$scheme = $context->getScheme();
|
||||
|
||||
if ('HEAD' === $requestMethod) {
|
||||
$canonicalMethod = 'GET';
|
||||
}
|
||||
|
||||
|
||||
if (0 === strpos($pathinfo, '/rootprefix')) {
|
||||
// static
|
||||
if ($pathinfo === '/rootprefix/test') {
|
||||
if ('/rootprefix/test' === $pathinfo) {
|
||||
return array('_route' => 'static');
|
||||
}
|
||||
|
||||
@ -41,7 +49,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
}
|
||||
|
||||
// with-condition
|
||||
if ($pathinfo === '/with-condition' && ($context->getMethod() == "GET")) {
|
||||
if ('/with-condition' === $pathinfo && ($context->getMethod() == "GET")) {
|
||||
return array('_route' => 'with-condition');
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
|
||||
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
|
||||
use Symfony\Component\Routing\RequestContext;
|
||||
|
||||
/**
|
||||
* ProjectUrlMatcher.
|
||||
*
|
||||
* This class has been auto-generated
|
||||
* by the Symfony Routing Component.
|
||||
*/
|
||||
class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
|
||||
{
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct(RequestContext $context)
|
||||
{
|
||||
$this->context = $context;
|
||||
}
|
||||
|
||||
public function match($pathinfo)
|
||||
{
|
||||
$allow = array();
|
||||
$pathinfo = rawurldecode($pathinfo);
|
||||
$trimmedPathinfo = rtrim($pathinfo, '/');
|
||||
$context = $this->context;
|
||||
$request = $this->request;
|
||||
$requestMethod = $canonicalMethod = $context->getMethod();
|
||||
$scheme = $context->getScheme();
|
||||
|
||||
if ('HEAD' === $requestMethod) {
|
||||
$canonicalMethod = 'GET';
|
||||
}
|
||||
|
||||
|
||||
// just_head
|
||||
if ('/just_head' === $pathinfo) {
|
||||
if ('HEAD' !== $requestMethod) {
|
||||
$allow[] = 'HEAD';
|
||||
goto not_just_head;
|
||||
}
|
||||
|
||||
return array('_route' => 'just_head');
|
||||
}
|
||||
not_just_head:
|
||||
|
||||
// head_and_get
|
||||
if ('/head_and_get' === $pathinfo) {
|
||||
if ('GET' !== $canonicalMethod) {
|
||||
$allow[] = 'GET';
|
||||
goto not_head_and_get;
|
||||
}
|
||||
|
||||
return array('_route' => 'head_and_get');
|
||||
}
|
||||
not_head_and_get:
|
||||
|
||||
if (0 === strpos($pathinfo, '/p')) {
|
||||
// post_and_head
|
||||
if ('/post_and_get' === $pathinfo) {
|
||||
if (!in_array($requestMethod, array('POST', 'HEAD'))) {
|
||||
$allow = array_merge($allow, array('POST', 'HEAD'));
|
||||
goto not_post_and_head;
|
||||
}
|
||||
|
||||
return array('_route' => 'post_and_head');
|
||||
}
|
||||
not_post_and_head:
|
||||
|
||||
if (0 === strpos($pathinfo, '/put_and_post')) {
|
||||
// put_and_post
|
||||
if ('/put_and_post' === $pathinfo) {
|
||||
if (!in_array($requestMethod, array('PUT', 'POST'))) {
|
||||
$allow = array_merge($allow, array('PUT', 'POST'));
|
||||
goto not_put_and_post;
|
||||
}
|
||||
|
||||
return array('_route' => 'put_and_post');
|
||||
}
|
||||
not_put_and_post:
|
||||
|
||||
// put_and_get_and_head
|
||||
if ('/put_and_post' === $pathinfo) {
|
||||
if (!in_array($canonicalMethod, array('PUT', 'GET'))) {
|
||||
$allow = array_merge($allow, array('PUT', 'GET'));
|
||||
goto not_put_and_get_and_head;
|
||||
}
|
||||
|
||||
return array('_route' => 'put_and_get_and_head');
|
||||
}
|
||||
not_put_and_get_and_head:
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
|
||||
}
|
||||
}
|
@ -279,10 +279,59 @@ class PhpMatcherDumperTest extends TestCase
|
||||
$route->setCondition('context.getMethod() == "GET"');
|
||||
$rootprefixCollection->add('with-condition', $route);
|
||||
|
||||
/* test case 4 */
|
||||
$headMatchCasesCollection = new RouteCollection();
|
||||
$headMatchCasesCollection->add('just_head', new Route(
|
||||
'/just_head',
|
||||
array(),
|
||||
array(),
|
||||
array(),
|
||||
'',
|
||||
array(),
|
||||
array('HEAD')
|
||||
));
|
||||
$headMatchCasesCollection->add('head_and_get', new Route(
|
||||
'/head_and_get',
|
||||
array(),
|
||||
array(),
|
||||
array(),
|
||||
'',
|
||||
array(),
|
||||
array('GET', 'HEAD')
|
||||
));
|
||||
$headMatchCasesCollection->add('post_and_head', new Route(
|
||||
'/post_and_get',
|
||||
array(),
|
||||
array(),
|
||||
array(),
|
||||
'',
|
||||
array(),
|
||||
array('POST', 'HEAD')
|
||||
));
|
||||
$headMatchCasesCollection->add('put_and_post', new Route(
|
||||
'/put_and_post',
|
||||
array(),
|
||||
array(),
|
||||
array(),
|
||||
'',
|
||||
array(),
|
||||
array('PUT', 'POST')
|
||||
));
|
||||
$headMatchCasesCollection->add('put_and_get_and_head', new Route(
|
||||
'/put_and_post',
|
||||
array(),
|
||||
array(),
|
||||
array(),
|
||||
'',
|
||||
array(),
|
||||
array('PUT', 'GET', 'HEAD')
|
||||
));
|
||||
|
||||
return array(
|
||||
array($collection, 'url_matcher1.php', array()),
|
||||
array($redirectCollection, 'url_matcher2.php', array('base_class' => 'Symfony\Component\Routing\Tests\Fixtures\RedirectableUrlMatcher')),
|
||||
array($rootprefixCollection, 'url_matcher3.php', array()),
|
||||
array($headMatchCasesCollection, 'url_matcher4.php', array()),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user