Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

performance improvement in PhpMatcherDumper

  • Loading branch information...
commit 56c1e31e8a3cab8376a5825cf03c649debd0987a 1 parent 0c7b291
@Tobion Tobion authored
View
88 src/Symfony/Component/Routing/Matcher/Dumper/PhpMatcherDumper.php
@@ -55,7 +55,7 @@ public function dump(array $options = array())
private function addMatcher($supportsRedirections)
{
// we need to deep clone the routes as we will modify the structure to optimize the dump
- $code = implode("\n", $this->compileRoutes(clone $this->getRoutes(), $supportsRedirections));
+ $code = rtrim($this->compileRoutes(clone $this->getRoutes(), $supportsRedirections), "\n");
return <<<EOF
@@ -65,6 +65,7 @@ public function match(\$pathinfo)
\$pathinfo = urldecode(\$pathinfo);
$code
+
throw 0 < count(\$allow) ? new MethodNotAllowedException(array_unique(\$allow)) : new ResourceNotFoundException();
}
@@ -73,7 +74,7 @@ public function match(\$pathinfo)
private function compileRoutes(RouteCollection $routes, $supportsRedirections, $parentPrefix = null)
{
- $code = array();
+ $code = '';
$routeIterator = $routes->getIterator();
$keys = array_keys($routeIterator->getArrayCopy());
@@ -86,10 +87,11 @@ private function compileRoutes(RouteCollection $routes, $supportsRedirections, $
if ($route instanceof RouteCollection) {
$prefix = $route->getPrefix();
$optimizable = $prefix && count($route->all()) > 1 && false === strpos($route->getPrefix(), '{');
- $indent = '';
+ $optimized = false;
+
if ($optimizable) {
for ($j = $i; $j < $keysCount; $j++) {
- if ($keys[$j] === null) {
+ if (null === $keys[$j]) {
continue;
}
@@ -113,28 +115,25 @@ private function compileRoutes(RouteCollection $routes, $supportsRedirections, $
}
if ($prefix !== $parentPrefix) {
- $code[] = sprintf(" if (0 === strpos(\$pathinfo, %s)) {", var_export($prefix, true));
- $indent = ' ';
+ $code .= sprintf(" if (0 === strpos(\$pathinfo, %s)) {\n", var_export($prefix, true));
+ $optimized = true;
}
}
- foreach ($this->compileRoutes($route, $supportsRedirections, $prefix) as $line) {
- foreach (explode("\n", $line) as $l) {
- if ($l) {
- $code[] = $indent.$l;
- } else {
- $code[] = $l;
+ if ($optimized) {
+ foreach (explode("\n", $this->compileRoutes($route, $supportsRedirections, $prefix)) as $line) {
+ if ('' !== $line) {
+ $code .= ' '; // apply extra indention
}
+ $code .= $line."\n";
}
- }
-
- if ($optimizable && $prefix !== $parentPrefix) {
- $code[] = " }\n";
+ $code = substr($code, 0, -2); // remove redundant last two line breaks
+ $code .= " }\n\n";
+ } else {
+ $code .= $this->compileRoutes($route, $supportsRedirections, $prefix);
}
} else {
- foreach ($this->compileRoute($route, $name, $supportsRedirections, $parentPrefix) as $line) {
- $code[] = $line;
- }
+ $code .= $this->compileRoute($route, $name, $supportsRedirections, $parentPrefix)."\n";
}
}
@@ -143,12 +142,13 @@ private function compileRoutes(RouteCollection $routes, $supportsRedirections, $
private function compileRoute(Route $route, $name, $supportsRedirections, $parentPrefix = null)
{
- $code = array();
+ $code = '';
$compiledRoute = $route->compile();
$conditions = array();
$hasTrailingSlash = false;
$matches = false;
$methods = array();
+
if ($req = $route->getRequirement('_method')) {
$methods = explode('|', strtoupper($req));
// GET and HEAD are equivalent
@@ -156,6 +156,7 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
$methods[] = 'HEAD';
}
}
+
$supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('HEAD', $methods));
if (!count($compiledRoute->getVariables()) && false !== preg_match('#^(.)\^(?P<url>.*?)\$\1#', str_replace(array("\n", ' '), '', $compiledRoute->getRegex()), $m)) {
@@ -182,39 +183,42 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
$conditions = implode(' && ', $conditions);
- $gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name);
-
- $code[] = <<<EOF
+ $code .= <<<EOF
// $name
if ($conditions) {
+
EOF;
if ($methods) {
+ $gotoname = 'not_'.preg_replace('/[^A-Za-z0-9_]/', '', $name);
+
if (1 === count($methods)) {
- $code[] = <<<EOF
+ $code .= <<<EOF
if (\$this->context->getMethod() != '$methods[0]') {
\$allow[] = '$methods[0]';
goto $gotoname;
}
+
EOF;
} else {
- $methods = implode('\', \'', $methods);
- $code[] = <<<EOF
+ $methods = implode("', '", $methods);
+ $code .= <<<EOF
if (!in_array(\$this->context->getMethod(), array('$methods'))) {
\$allow = array_merge(\$allow, array('$methods'));
goto $gotoname;
}
+
EOF;
}
}
if ($hasTrailingSlash) {
- $code[] = sprintf(<<<EOF
+ $code .= <<<EOF
if (substr(\$pathinfo, -1) !== '/') {
- return \$this->redirect(\$pathinfo.'/', '%s');
+ return \$this->redirect(\$pathinfo.'/', '$name');
}
-EOF
- , $name);
+
+EOF;
}
if ($scheme = $route->getRequirement('_scheme')) {
@@ -222,34 +226,32 @@ private function compileRoute(Route $route, $name, $supportsRedirections, $paren
throw new \LogicException('The "_scheme" requirement is only supported for URL matchers that implement RedirectableUrlMatcherInterface.');
}
- $code[] = sprintf(<<<EOF
+ $code .= <<<EOF
if (\$this->context->getScheme() !== '$scheme') {
- return \$this->redirect(\$pathinfo, '%s', '$scheme');
+ return \$this->redirect(\$pathinfo, '$name', '$scheme');
}
-EOF
- , $name);
+
+EOF;
}
// optimize parameters array
if (true === $matches && $compiledRoute->getDefaults()) {
- $code[] = sprintf(" return array_merge(\$this->mergeDefaults(\$matches, %s), array('_route' => '%s'));"
+ $code .= sprintf(" return array_merge(\$this->mergeDefaults(\$matches, %s), array('_route' => '%s'));\n"
, str_replace("\n", '', var_export($compiledRoute->getDefaults(), true)), $name);
} elseif (true === $matches) {
- $code[] = sprintf(" \$matches['_route'] = '%s';", $name);
- $code[] = sprintf(" return \$matches;", $name);
+ $code .= sprintf(" \$matches['_route'] = '%s';\n", $name);
+ $code .= " return \$matches;\n";
} elseif ($compiledRoute->getDefaults()) {
- $code[] = sprintf(' return %s;', str_replace("\n", '', var_export(array_merge($compiledRoute->getDefaults(), array('_route' => $name)), true)));
+ $code .= sprintf(" return %s;\n", str_replace("\n", '', var_export(array_merge($compiledRoute->getDefaults(), array('_route' => $name)), true)));
} else {
- $code[] = sprintf(" return array('_route' => '%s');", $name);
+ $code .= sprintf(" return array('_route' => '%s');\n", $name);
}
- $code[] = " }";
+ $code .= " }\n";
if ($methods) {
- $code[] = " $gotoname:";
+ $code .= " $gotoname:\n";
}
- $code[] = '';
-
return $code;
}
View
2  src/Symfony/Component/Routing/RouteCollection.php
@@ -73,7 +73,7 @@ public function setParent(RouteCollection $parent)
}
/**
- * Gets the current RouteCollection as an Iterator.
+ * Gets the current RouteCollection as an Iterator that includes all routes and child route collections.
*
* @return \ArrayIterator An \ArrayIterator interface
*/
View
2  src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher1.php
@@ -131,7 +131,6 @@ public function match($pathinfo)
$matches['_route'] = 'bar2';
return $matches;
}
-
}
// overriden
@@ -149,7 +148,6 @@ public function match($pathinfo)
$matches['_route'] = 'foo4';
return $matches;
}
-
}
// foo3
View
2  src/Symfony/Component/Routing/Tests/Fixtures/dumper/url_matcher2.php
@@ -137,7 +137,6 @@ public function match($pathinfo)
$matches['_route'] = 'bar2';
return $matches;
}
-
}
// overriden
@@ -155,7 +154,6 @@ public function match($pathinfo)
$matches['_route'] = 'foo4';
return $matches;
}
-
}
// foo3
View
6 src/Symfony/Component/Routing/Tests/Matcher/Dumper/PhpMatcherDumperTest.php
@@ -20,11 +20,11 @@ class PhpMatcherDumperTest extends \PHPUnit_Framework_TestCase
{
public function testDump()
{
- $dumper = new PhpMatcherDumper($this->getRouteCollection(), new RequestContext());
+ $collection = $this->getRouteCollection();
- $this->assertStringEqualsFile(__DIR__.'/../../Fixtures/dumper/url_matcher1.php', $dumper->dump(), '->dump() dumps basic routes to the correct PHP file.');
+ $dumper = new PhpMatcherDumper($collection, new RequestContext());
- $collection = $this->getRouteCollection();
+ $this->assertStringEqualsFile(__DIR__.'/../../Fixtures/dumper/url_matcher1.php', $dumper->dump(), '->dump() dumps basic routes to the correct PHP file.');
// force HTTPS redirection
$collection->add('secure', new Route(
Please sign in to comment.
Something went wrong with that request. Please try again.