Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[Routing] Optimised dumped router matcher, prevent unneeded function calls. #21755

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
62 changes: 48 additions & 14 deletions 62 src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,16 @@ 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';
}


$code

Expand All @@ -133,7 +141,7 @@ private function compileRoutes(RouteCollection $routes, $supportsRedirections)
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;
}

Expand Down Expand Up @@ -217,20 +225,15 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
$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();

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This removed N trim calls.

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) {
Expand Down Expand Up @@ -263,26 +266,57 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
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;
Copy link
Contributor

@GuilhemN GuilhemN Feb 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has the use of the goto ever been discussed?
It seems like here we only need to reverse the conditions to get ride of it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm checking this out now, if proven to be effective I'll create another PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GuilhemN I suspected it to have some effect, but it did literally nothing.

}


EOF;
} else {
$methods = implode("', '", $methods);
$code .= <<<EOF
if (!in_array(\$$methodVariable, array('$methods'))) {
\$allow = array_merge(\$allow, array('$methods'));
goto $gotoname;
}


EOF;
}
}
}

Expand All @@ -303,7 +337,7 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
$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));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,16 @@ 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';
}


// foo
if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?P<bar>baz|symfony)$#s', $pathinfo, $matches)) {
Expand All @@ -35,8 +43,8 @@ public function match($pathinfo)
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;
}

Expand All @@ -46,8 +54,8 @@ public function match($pathinfo)

// 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;
}

Expand All @@ -60,17 +68,17 @@ public function match($pathinfo)
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');
}

Expand All @@ -83,7 +91,7 @@ public function match($pathinfo)

// baz5
if (preg_match('#^/test/(?P<foo>[^/]++)/$#s', $pathinfo, $matches)) {
if ($this->context->getMethod() != 'POST') {
if ('POST' !== $canonicalMethod) {
$allow[] = 'POST';
goto not_baz5;
}
Expand All @@ -94,7 +102,7 @@ public function match($pathinfo)

// baz.baz6
if (preg_match('#^/test/(?P<foo>[^/]++)/$#s', $pathinfo, $matches)) {
if ($this->context->getMethod() != 'PUT') {
if ('PUT' !== $canonicalMethod) {
$allow[] = 'PUT';
goto not_bazbaz6;
}
Expand All @@ -106,7 +114,7 @@ public function match($pathinfo)
}

// foofoo
if ($pathinfo === '/foofoo') {
if ('/foofoo' === $pathinfo) {
return array ( 'def' => 'test', '_route' => 'foofoo',);
}

Expand All @@ -116,7 +124,7 @@ public function match($pathinfo)
}

// space
if ($pathinfo === '/spa ce') {
if ('/spa ce' === $pathinfo) {
return array('_route' => 'space');
}

Expand Down Expand Up @@ -161,12 +169,12 @@ public function match($pathinfo)
}

// 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');
}

Expand All @@ -184,7 +192,7 @@ public function match($pathinfo)

if (0 === strpos($pathinfo, '/aba')) {
// ababa
if ($pathinfo === '/ababa') {
if ('/ababa' === $pathinfo) {
return array('_route' => 'ababa');
}

Expand All @@ -195,59 +203,59 @@ public function match($pathinfo)

}

$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');
}

}

if (preg_match('#^b\\.example\\.com$#si', $host, $hostMatches)) {
// route3
if ($pathinfo === '/c2/route3') {
if ('/c2/route3' === $pathinfo) {
return array('_route' => 'route3');
}

}

if (preg_match('#^a\\.example\\.com$#si', $host, $hostMatches)) {
// route4
if ($pathinfo === '/route4') {
if ('/route4' === $pathinfo) {
return array('_route' => 'route4');
}

}

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',));
}

Expand Down Expand Up @@ -280,15 +288,15 @@ public function match($pathinfo)
}

// route17
if ($pathinfo === '/route17') {
if ('/route17' === $pathinfo) {
return array('_route' => 'route17');
}

}

if (0 === strpos($pathinfo, '/a')) {
// a
if ($pathinfo === '/a/a...') {
if ('/a/a...' === $pathinfo) {
return array('_route' => 'a');
}

Expand Down
Loading
Morty Proxy This is a proxified and sanitized view of the page, visit original site.