merged branch Tobion/routing-centos (PR #6062)

This PR was merged into the 2.1 branch.

Commits
-------

1daefa5 [Routing] made it compatible with older PCRE version (pre 8)

Discussion
----------

[Routing] compatibility with older PCRE version (pre 8)

fixes #4093

Ok I changed my mind about this issue.
1. I figured more people are affected than I thought and CentOS is stubborn.
2. Symfony still uses the old regex style `?P<param>` in several other components. So also doing so in the routing makes it more consistent.
3. Even if it's definitely not good to use an over 6 year old PCRE version with a recent PHP version, we can still try to provide the best experience. It doesn't mean we support outdated software stacks of custom PHP compilations as we won't and cannot specifically test against it.

@fabpot: I will do a seperate PR on master when you merged this because the code changed alot in master so it cannot easily be merged I guess. I will also convert the symfony requirement for PCRE in the requirements check to a recommendation.
This commit is contained in:
Fabien Potencier 2012-11-19 11:35:29 +01:00
commit 8f33f2ea86
7 changed files with 51 additions and 51 deletions

View File

@ -55,7 +55,7 @@ class ApacheMatcherDumper extends MatcherDumper
if (strlen($regex) < 2 || 0 === $regexPatternEnd) {
throw new \LogicException('The "%s" route regex "%s" is invalid', $name, $regex);
}
$regex = preg_replace('/\?<.+?>/', '', substr($regex, 1, $regexPatternEnd - 1));
$regex = preg_replace('/\?P<.+?>/', '', substr($regex, 1, $regexPatternEnd - 1));
$regex = '^'.self::escape(preg_quote($options['base_uri']).substr($regex, 1), ' ', '\\');
$methods = array();

View File

@ -191,7 +191,7 @@ EOF;
$supportsTrailingSlash = $supportsRedirections && (!$methods || in_array('HEAD', $methods));
if (!count($compiledRoute->getVariables()) && false !== preg_match('#^(.)\^(?<url>.*?)\$\1#', $compiledRoute->getRegex(), $m)) {
if (!count($compiledRoute->getVariables()) && false !== preg_match('#^(.)\^(?P<url>.*?)\$\1#', $compiledRoute->getRegex(), $m)) {
if ($supportsTrailingSlash && substr($m['url'], -1) === '/') {
$conditions[] = sprintf("rtrim(\$pathinfo, '/') === %s", var_export(rtrim(str_replace('\\', '', $m['url']), '/'), true));
$hasTrailingSlash = true;

View File

@ -111,9 +111,9 @@ class RouteCompiler implements RouteCompilerInterface
// Variable tokens
if (0 === $index && 0 === $firstOptional) {
// When the only token is an optional variable token, the separator is required
return sprintf('%s(?<%s>%s)?', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]);
return sprintf('%s(?P<%s>%s)?', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]);
} else {
$regexp = sprintf('%s(?<%s>%s)', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]);
$regexp = sprintf('%s(?P<%s>%s)', preg_quote($token[1], self::REGEX_DELIMITER), $token[3], $token[2]);
if ($index >= $firstOptional) {
// Enclose each optional token in a subpattern to make it optional.
// "?:" means it is non-capturing, i.e. the portion of the subject string that

View File

@ -26,12 +26,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
$pathinfo = rawurldecode($pathinfo);
// foo
if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?<bar>baz|symfony)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?P<bar>baz|symfony)$#s', $pathinfo, $matches)) {
return array_merge($this->mergeDefaults($matches, array ( 'def' => 'test',)), array('_route' => 'foo'));
}
// bar
if (0 === strpos($pathinfo, '/bar') && preg_match('#^/bar/(?<foo>[^/]+)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/bar') && preg_match('#^/bar/(?P<foo>[^/]+)$#s', $pathinfo, $matches)) {
if (!in_array($this->context->getMethod(), array('GET', 'HEAD'))) {
$allow = array_merge($allow, array('GET', 'HEAD'));
goto not_bar;
@ -44,7 +44,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
not_bar:
// barhead
if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?<foo>[^/]+)$#s', $pathinfo, $matches)) {
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'));
goto not_barhead;
@ -72,14 +72,14 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
// baz4
if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?<foo>[^/]+)/$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P<foo>[^/]+)/$#s', $pathinfo, $matches)) {
$matches['_route'] = 'baz4';
return $matches;
}
// baz5
if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?<foo>[^/]+)/$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P<foo>[^/]+)/$#s', $pathinfo, $matches)) {
if ($this->context->getMethod() != 'POST') {
$allow[] = 'POST';
goto not_baz5;
@ -92,7 +92,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
not_baz5:
// baz.baz6
if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?<foo>[^/]+)/$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P<foo>[^/]+)/$#s', $pathinfo, $matches)) {
if ($this->context->getMethod() != 'PUT') {
$allow[] = 'PUT';
goto not_bazbaz6;
@ -110,7 +110,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
// quoter
if (preg_match('#^/(?<quoter>[\']+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/(?P<quoter>[\']+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'quoter';
return $matches;
@ -124,14 +124,14 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
if (0 === strpos($pathinfo, '/a')) {
if (0 === strpos($pathinfo, '/a/b\'b')) {
// foo1
if (preg_match('#^/a/b\'b/(?<foo>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<foo>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'foo1';
return $matches;
}
// bar1
if (preg_match('#^/a/b\'b/(?<bar>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<bar>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'bar1';
return $matches;
@ -140,7 +140,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
// overridden
if (preg_match('#^/a/(?<var>.*)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/(?P<var>.*)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'overridden';
return $matches;
@ -148,14 +148,14 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
if (0 === strpos($pathinfo, '/a/b\'b')) {
// foo2
if (preg_match('#^/a/b\'b/(?<foo1>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<foo1>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'foo2';
return $matches;
}
// bar2
if (preg_match('#^/a/b\'b/(?<bar1>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<bar1>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'bar2';
return $matches;
@ -167,7 +167,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
if (0 === strpos($pathinfo, '/multi')) {
// helloWorld
if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?<who>[^/]+))?$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P<who>[^/]+))?$#s', $pathinfo, $matches)) {
return array_merge($this->mergeDefaults($matches, array ( 'who' => 'World!',)), array('_route' => 'helloWorld'));
}
@ -184,14 +184,14 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
// foo3
if (preg_match('#^/(?<_locale>[^/]+)/b/(?<foo>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/(?P<_locale>[^/]+)/b/(?P<foo>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'foo3';
return $matches;
}
// bar3
if (preg_match('#^/(?<_locale>[^/]+)/b/(?<bar>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/(?P<_locale>[^/]+)/b/(?P<bar>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'bar3';
return $matches;
@ -203,7 +203,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
// foo4
if (0 === strpos($pathinfo, '/aba') && preg_match('#^/aba/(?<foo>[^/]+)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/aba') && preg_match('#^/aba/(?P<foo>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'foo4';
return $matches;
@ -217,14 +217,14 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
if (0 === strpos($pathinfo, '/a/b')) {
// b
if (preg_match('#^/a/b/(?<var>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b/(?P<var>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'b';
return $matches;
}
// c
if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?<var>[^/]+)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P<var>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'c';
return $matches;

View File

@ -26,12 +26,12 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
$pathinfo = rawurldecode($pathinfo);
// foo
if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?<bar>baz|symfony)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/foo') && preg_match('#^/foo/(?P<bar>baz|symfony)$#s', $pathinfo, $matches)) {
return array_merge($this->mergeDefaults($matches, array ( 'def' => 'test',)), array('_route' => 'foo'));
}
// bar
if (0 === strpos($pathinfo, '/bar') && preg_match('#^/bar/(?<foo>[^/]+)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/bar') && preg_match('#^/bar/(?P<foo>[^/]+)$#s', $pathinfo, $matches)) {
if (!in_array($this->context->getMethod(), array('GET', 'HEAD'))) {
$allow = array_merge($allow, array('GET', 'HEAD'));
goto not_bar;
@ -44,7 +44,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
not_bar:
// barhead
if (0 === strpos($pathinfo, '/barhead') && preg_match('#^/barhead/(?<foo>[^/]+)$#s', $pathinfo, $matches)) {
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'));
goto not_barhead;
@ -76,7 +76,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
// baz4
if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?<foo>[^/]+)/?$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P<foo>[^/]+)/?$#s', $pathinfo, $matches)) {
if (substr($pathinfo, -1) !== '/') {
return $this->redirect($pathinfo.'/', 'baz4');
}
@ -87,7 +87,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
// baz5
if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?<foo>[^/]+)/$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P<foo>[^/]+)/$#s', $pathinfo, $matches)) {
if ($this->context->getMethod() != 'POST') {
$allow[] = 'POST';
goto not_baz5;
@ -100,7 +100,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
not_baz5:
// baz.baz6
if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?<foo>[^/]+)/$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/test') && preg_match('#^/test/(?P<foo>[^/]+)/$#s', $pathinfo, $matches)) {
if ($this->context->getMethod() != 'PUT') {
$allow[] = 'PUT';
goto not_bazbaz6;
@ -118,7 +118,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
// quoter
if (preg_match('#^/(?<quoter>[\']+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/(?P<quoter>[\']+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'quoter';
return $matches;
@ -132,14 +132,14 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
if (0 === strpos($pathinfo, '/a')) {
if (0 === strpos($pathinfo, '/a/b\'b')) {
// foo1
if (preg_match('#^/a/b\'b/(?<foo>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<foo>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'foo1';
return $matches;
}
// bar1
if (preg_match('#^/a/b\'b/(?<bar>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<bar>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'bar1';
return $matches;
@ -148,7 +148,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
// overridden
if (preg_match('#^/a/(?<var>.*)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/(?P<var>.*)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'overridden';
return $matches;
@ -156,14 +156,14 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
if (0 === strpos($pathinfo, '/a/b\'b')) {
// foo2
if (preg_match('#^/a/b\'b/(?<foo1>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<foo1>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'foo2';
return $matches;
}
// bar2
if (preg_match('#^/a/b\'b/(?<bar1>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b\'b/(?P<bar1>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'bar2';
return $matches;
@ -175,7 +175,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
if (0 === strpos($pathinfo, '/multi')) {
// helloWorld
if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?<who>[^/]+))?$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/multi/hello') && preg_match('#^/multi/hello(?:/(?P<who>[^/]+))?$#s', $pathinfo, $matches)) {
return array_merge($this->mergeDefaults($matches, array ( 'who' => 'World!',)), array('_route' => 'helloWorld'));
}
@ -196,14 +196,14 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
// foo3
if (preg_match('#^/(?<_locale>[^/]+)/b/(?<foo>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/(?P<_locale>[^/]+)/b/(?P<foo>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'foo3';
return $matches;
}
// bar3
if (preg_match('#^/(?<_locale>[^/]+)/b/(?<bar>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/(?P<_locale>[^/]+)/b/(?P<bar>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'bar3';
return $matches;
@ -215,7 +215,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
}
// foo4
if (0 === strpos($pathinfo, '/aba') && preg_match('#^/aba/(?<foo>[^/]+)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/aba') && preg_match('#^/aba/(?P<foo>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'foo4';
return $matches;
@ -229,14 +229,14 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Tests\Fixtures\Redirec
if (0 === strpos($pathinfo, '/a/b')) {
// b
if (preg_match('#^/a/b/(?<var>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/a/b/(?P<var>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'b';
return $matches;
}
// c
if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?<var>[^/]+)$#s', $pathinfo, $matches)) {
if (0 === strpos($pathinfo, '/a/b/c') && preg_match('#^/a/b/c/(?P<var>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'c';
return $matches;

View File

@ -32,7 +32,7 @@ class ProjectUrlMatcher extends Symfony\Component\Routing\Matcher\UrlMatcher
}
// dynamic
if (preg_match('#^/rootprefix/(?<var>[^/]+)$#s', $pathinfo, $matches)) {
if (preg_match('#^/rootprefix/(?P<var>[^/]+)$#s', $pathinfo, $matches)) {
$matches['_route'] = 'dynamic';
return $matches;

View File

@ -43,7 +43,7 @@ class RouteCompilerTest extends \PHPUnit_Framework_TestCase
array(
'Route with a variable',
array('/foo/{bar}'),
'/foo', '#^/foo/(?<bar>[^/]+)$#s', array('bar'), array(
'/foo', '#^/foo/(?P<bar>[^/]+)$#s', array('bar'), array(
array('variable', '/', '[^/]+', 'bar'),
array('text', '/foo'),
)),
@ -51,7 +51,7 @@ class RouteCompilerTest extends \PHPUnit_Framework_TestCase
array(
'Route with a variable that has a default value',
array('/foo/{bar}', array('bar' => 'bar')),
'/foo', '#^/foo(?:/(?<bar>[^/]+))?$#s', array('bar'), array(
'/foo', '#^/foo(?:/(?P<bar>[^/]+))?$#s', array('bar'), array(
array('variable', '/', '[^/]+', 'bar'),
array('text', '/foo'),
)),
@ -59,7 +59,7 @@ class RouteCompilerTest extends \PHPUnit_Framework_TestCase
array(
'Route with several variables',
array('/foo/{bar}/{foobar}'),
'/foo', '#^/foo/(?<bar>[^/]+)/(?<foobar>[^/]+)$#s', array('bar', 'foobar'), array(
'/foo', '#^/foo/(?P<bar>[^/]+)/(?P<foobar>[^/]+)$#s', array('bar', 'foobar'), array(
array('variable', '/', '[^/]+', 'foobar'),
array('variable', '/', '[^/]+', 'bar'),
array('text', '/foo'),
@ -68,7 +68,7 @@ class RouteCompilerTest extends \PHPUnit_Framework_TestCase
array(
'Route with several variables that have default values',
array('/foo/{bar}/{foobar}', array('bar' => 'bar', 'foobar' => '')),
'/foo', '#^/foo(?:/(?<bar>[^/]+)(?:/(?<foobar>[^/]+))?)?$#s', array('bar', 'foobar'), array(
'/foo', '#^/foo(?:/(?P<bar>[^/]+)(?:/(?P<foobar>[^/]+))?)?$#s', array('bar', 'foobar'), array(
array('variable', '/', '[^/]+', 'foobar'),
array('variable', '/', '[^/]+', 'bar'),
array('text', '/foo'),
@ -77,7 +77,7 @@ class RouteCompilerTest extends \PHPUnit_Framework_TestCase
array(
'Route with several variables but some of them have no default values',
array('/foo/{bar}/{foobar}', array('bar' => 'bar')),
'/foo', '#^/foo/(?<bar>[^/]+)/(?<foobar>[^/]+)$#s', array('bar', 'foobar'), array(
'/foo', '#^/foo/(?P<bar>[^/]+)/(?P<foobar>[^/]+)$#s', array('bar', 'foobar'), array(
array('variable', '/', '[^/]+', 'foobar'),
array('variable', '/', '[^/]+', 'bar'),
array('text', '/foo'),
@ -86,21 +86,21 @@ class RouteCompilerTest extends \PHPUnit_Framework_TestCase
array(
'Route with an optional variable as the first segment',
array('/{bar}', array('bar' => 'bar')),
'', '#^/(?<bar>[^/]+)?$#s', array('bar'), array(
'', '#^/(?P<bar>[^/]+)?$#s', array('bar'), array(
array('variable', '/', '[^/]+', 'bar'),
)),
array(
'Route with an optional variable as the first segment with requirements',
array('/{bar}', array('bar' => 'bar'), array('bar' => '(foo|bar)')),
'', '#^/(?<bar>(foo|bar))?$#s', array('bar'), array(
'', '#^/(?P<bar>(foo|bar))?$#s', array('bar'), array(
array('variable', '/', '(foo|bar)', 'bar'),
)),
array(
'Route with only optional variables',
array('/{foo}/{bar}', array('foo' => 'foo', 'bar' => 'bar')),
'', '#^/(?<foo>[^/]+)?(?:/(?<bar>[^/]+))?$#s', array('foo', 'bar'), array(
'', '#^/(?P<foo>[^/]+)?(?:/(?P<bar>[^/]+))?$#s', array('foo', 'bar'), array(
array('variable', '/', '[^/]+', 'bar'),
array('variable', '/', '[^/]+', 'foo'),
)),
@ -108,7 +108,7 @@ class RouteCompilerTest extends \PHPUnit_Framework_TestCase
array(
'Route with a variable in last position',
array('/foo-{bar}'),
'/foo', '#^/foo\-(?<bar>[^\-]+)$#s', array('bar'), array(
'/foo', '#^/foo\-(?P<bar>[^\-]+)$#s', array('bar'), array(
array('variable', '-', '[^\-]+', 'bar'),
array('text', '/foo'),
)),
@ -116,7 +116,7 @@ class RouteCompilerTest extends \PHPUnit_Framework_TestCase
array(
'Route with a format',
array('/foo/{bar}.{_format}'),
'/foo', '#^/foo/(?<bar>[^/\.]+)\.(?<_format>[^\.]+)$#s', array('bar', '_format'), array(
'/foo', '#^/foo/(?P<bar>[^/\.]+)\.(?P<_format>[^\.]+)$#s', array('bar', '_format'), array(
array('variable', '.', '[^\.]+', '_format'),
array('variable', '/', '[^/\.]+', 'bar'),
array('text', '/foo'),