diff --git a/src/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php b/src/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php index 76612e6184..55aac6b707 100644 --- a/src/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php +++ b/src/Symfony/Component/Routing/Matcher/ApacheUrlMatcher.php @@ -39,7 +39,7 @@ class ApacheUrlMatcher extends UrlMatcher $allow = array(); $route = null; - foreach ($_SERVER as $key => $value) { + foreach ($this->denormalizeValues($_SERVER) as $key => $value) { $name = $key; // skip non-routing variables @@ -91,4 +91,28 @@ class ApacheUrlMatcher extends UrlMatcher 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; + } } diff --git a/src/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php b/src/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php index 895987c702..01d8c03589 100644 --- a/src/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php +++ b/src/Symfony/Component/Routing/Matcher/Dumper/ApacheMatcherDumper.php @@ -132,7 +132,7 @@ class ApacheMatcherDumper extends MatcherDumper foreach ($compiledRoute->getPathVariables() as $i => $variable) { $variables[] = 'E=_ROUTING_param_'.$variable.':%'.($i + 1); } - foreach ($route->getDefaults() as $key => $value) { + foreach ($this->normalizeValues($route->getDefaults()) as $key => $value) { $variables[] = 'E=_ROUTING_default_'.$key.':'.strtr($value, array( ':' => '\\:', '=' => '\\=', @@ -248,4 +248,27 @@ class ApacheMatcherDumper extends MatcherDumper return $output; } + + /** + * Normalizes an array of values. + * + * @param array $values + * + * @return string[] + */ + private function normalizeValues(array $values) + { + $normalizedValues = array(); + foreach ($values as $key => $value) { + if (is_array($value)) { + foreach ($value as $index => $bit) { + $normalizedValues[sprintf('%s[%s]', $key, $index)] = $bit; + } + } else { + $normalizedValues[$key] = (string) $value; + } + } + + return $normalizedValues; + } } diff --git a/src/Symfony/Component/Routing/Tests/Matcher/ApacheUrlMatcherTest.php b/src/Symfony/Component/Routing/Tests/Matcher/ApacheUrlMatcherTest.php index 6550911eb7..2810cbad51 100644 --- a/src/Symfony/Component/Routing/Tests/Matcher/ApacheUrlMatcherTest.php +++ b/src/Symfony/Component/Routing/Tests/Matcher/ApacheUrlMatcherTest.php @@ -90,6 +90,21 @@ class ApacheUrlMatcherTest extends \PHPUnit_Framework_TestCase '_route' => 'hello', ), ), + array( + 'Redirect with many ignored attributes', + '/legacy/{cat1}/{cat2}/{id}.html', + array( + '_ROUTING_route' => 'product_view', + '_ROUTING_param__controller' => 'FrameworkBundle:Redirect:redirect', + '_ROUTING_default_ignoreAttributes[0]' => 'attr_a', + '_ROUTING_default_ignoreAttributes[1]' => 'attr_b', + ), + array( + 'ignoreAttributes' => array('attr_a', 'attr_b'), + '_controller' => 'FrameworkBundle:Redirect:redirect', + '_route' => 'product_view', + ) + ), array( 'REDIRECT_ envs', '/hello/world', @@ -131,7 +146,7 @@ class ApacheUrlMatcherTest extends \PHPUnit_Framework_TestCase 'name' => 'world', '_route' => 'hello', ), - ), + ) ); } }