we don't need the logic to merge numeric keys, as we don't have them. I could also improve the genrated code by PhpMatcherDumper a little by saving a function call.
This PR was merged into the master branch.
Commits
-------
c7a8f7a [Routing] fixed possible parameters conflict in apache url matcher
Discussion
----------
[Routing] fixed possible parameters conflict in apache url matcher
Bug fix: yes
Feature addition: no
Backwards compatibility break: no (as long as rewrite rules are generated after upgrading)
Symfony2 tests pass: yes
- This fixes a conflict in route parameters:
The rewrite rules currently pass route informations through environment variables:
`_ROUTING_DEFAULT_x`: passes the default value of parameter x
`_ROUTING__allow_x`: passes the information that method x was allowed for this route
`_ROUTING_x`: passes the value of parameter x
The problem is that naming a route parameter `DEFAULT_*` or `_allow_*` would not behave as expected.
I fixed this by namespacing all environment variables; e.g. parameters are in `_ROUTING_param_*`, defaults in `_ROUTING_default_*`, etc.
- The PR fixes a second issue: sometimes the variables are prefixed with multiple REDIRECT_. This PR handles this case by ignoring them all.
- This also improves performance a little:
Matching a route with two parameters and two default parameters 100K times: (`$_SERVER` was copied from a real request, so with many non `_ROUTING_` variables)
master: 6.6s
this branch: 4.7s
---------------------------------------------------------------------------
by fabpot at 2012-10-27T13:37:24Z
Any news on this PR? Is it mergeable?
---------------------------------------------------------------------------
by arnaud-lb at 2012-10-27T14:50:08Z
There is an issue with default parameter values, I can't find how to fix that in a simple way. Before this PR, default values are never used (if a parameter is an optional not present in the url, the parameter's value is the empty string); after this PR, when a parameter is present and empty (e.g. a requirement like `.*`), its value is set to its default value.
---------------------------------------------------------------------------
by Tobion at 2012-10-29T01:36:08Z
The problem is, it's not consistent with the default php matcher. So one cannot safely exchange it with the apache matcher because it behaves differently under some (special) circumstances.
---------------------------------------------------------------------------
by fabpot at 2012-11-05T08:05:54Z
We need to move forward as I want to merge the hostname support in the routing ASAP to have plenty of time for feedback before the 2.2 release.
Does it sound reasonable to merge this PR as is an open a ticket about the remaining issue (which should not occur that often anyways)?
---------------------------------------------------------------------------
by arnaud-lb at 2012-11-05T09:22:02Z
@fabpot it sounds reasonable to me. Also, I've the hostname support branch is currently rebased so that it can be merged without this one.
---------------------------------------------------------------------------
by Tobion at 2012-11-11T21:50:20Z
Btw, does the ApacheMatcherDumper handle the _scheme requirement? It doesn't look like it. This would be another bug.
Anyway, we can probably merge this PR and open new issues for the remaining bugs.
* 2.1:
[ClassLoader] fixed unbracketed namespaces (closes#5747)
slight refactoring in UrlMatcher
[Form] Created test for DoctrineOrmTypeGuesser see #5790
[Form] Fixed DoctrineOrmTypeGuesser to guess the "required" option for to-one associations
Commits
-------
7464dcd added phpdoc
c413e7b [Routing] remove RequestContextAwareInterface from RequestMatcherInterface
921be34 [Routing] fix phpdoc
Discussion
----------
[Routing] RequestMatcherInterface doesn't need context
Matchers that implement RequestMatcherInterface should match a Request, thus they don't need the request context.
---------------------------------------------------------------------------
by travisbot at 2012-06-14T21:39:48Z
This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1624496) (merged f5ff1fe0 into 7c91ee57).
---------------------------------------------------------------------------
by schmittjoh at 2012-06-15T13:32:59Z
I think it makes sense to remove the RequestContext from the RequestMatcher.
---------------------------------------------------------------------------
by travisbot at 2012-06-15T15:54:28Z
This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1628931) (merged 7464dcd2 into f881d282).
---------------------------------------------------------------------------
by Tobion at 2012-06-26T12:32:06Z
Anything missing?
Commits
-------
680e732 [Routing] fix phpDoc
Discussion
----------
[Routing] fix phpDoc
using inheritdoc where possible and removing api tag when parent interface has one
as requested by stof and fabpot
---------------------------------------------------------------------------
by travisbot at 2012-06-09T16:14:53Z
This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1577508) (merged 0a44632a into f8a09db5).
---------------------------------------------------------------------------
by travisbot at 2012-06-10T19:36:25Z
This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1585766) (merged 680e732a into 7bec0786).
Commits
-------
2277500 [Routing][HttpKernel] Add RequestMatcherInterface.
Discussion
----------
[Routing][HttpKernel] Add RequestMatcherInterface.
First try at implementing #4351.
Bug fix: no
Feature addition: yes
Backwards compatibility break: no
Fixes the following tickets: -
Todo: -
License of the code: MIT
---------------------------------------------------------------------------
by travisbot at 2012-05-21T19:37:07Z
This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1392716) (merged 457496db into ea33d4d3).
---------------------------------------------------------------------------
by travisbot at 2012-05-21T19:47:51Z
This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1392939) (merged 78effa98 into ea33d4d3).
---------------------------------------------------------------------------
by everzet at 2012-05-21T20:17:03Z
No tests?
---------------------------------------------------------------------------
by travisbot at 2012-05-21T20:18:18Z
This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1393392) (merged 6564fb6a into ea33d4d3).
---------------------------------------------------------------------------
by schmittjoh at 2012-05-21T20:35:14Z
You need to remove the type-hint from the constructor, and probably add an exception instead where the matching methods are called to ensure that either ``UrlMatcherInterface``, or ``RequestMatcherInterface`` were passed. Alternatively, you could also add such a check to the constructor.
---------------------------------------------------------------------------
by fabpot at 2012-05-22T06:52:01Z
related to symfony/symfony#4020
---------------------------------------------------------------------------
by niklasf at 2012-05-25T11:11:45Z
Reverted the changes to UrlMatcher.php.
---------------------------------------------------------------------------
by fabpot at 2012-05-25T12:46:06Z
@niklasf: it looks good now except for the listener constructor (see @schmittjoh suggestion above). Can you fix that and add some unit tests to ensure that everything works as expected? Thanks.
---------------------------------------------------------------------------
by stof at 2012-05-25T12:52:59Z
Another solution could be to make the ``RequestMatcherInterface`` extend the ``MatcherInterface`` to keep the typehint in the constructor
---------------------------------------------------------------------------
by fabpot at 2012-05-25T13:52:26Z
I thought about that as well, but that does not make sense.
---------------------------------------------------------------------------
by stof at 2012-05-25T14:12:19Z
Well, the RouterInterface extends UrlMatcherInterface anyway (and it should stay this way as it would be a huge BC break) so I guess most people will implement both interfaces when implementing the RquestMatcherInterface
---------------------------------------------------------------------------
by travisbot at 2012-05-25T15:26:22Z
This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1433963) (merged 8f36204c into ff4d446c).
---------------------------------------------------------------------------
by travisbot at 2012-05-25T15:33:13Z
This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1433996) (merged 6d2f2cd9 into ff4d446c).
---------------------------------------------------------------------------
by travisbot at 2012-05-25T15:39:01Z
This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1434060) (merged 3c1d89e2 into ff4d446c).
---------------------------------------------------------------------------
by travisbot at 2012-05-25T22:06:34Z
This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1437398) (merged 3ab997c1 into ff4d446c).
---------------------------------------------------------------------------
by travisbot at 2012-05-25T22:06:47Z
This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1437385) (merged d8c0e387 into ff4d446c).
---------------------------------------------------------------------------
by fabpot at 2012-05-26T06:41:31Z
Can you add a note in the CHANGELOG of the component?
---------------------------------------------------------------------------
by travisbot at 2012-05-26T08:12:40Z
This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1440435) (merged c7458733 into 9e951991).
---------------------------------------------------------------------------
by niklasf at 2012-05-26T08:14:41Z
@fabpot: Sorry, not sure how: Under 2.1.0 or in a new section? As the first or last entry of the list?
---------------------------------------------------------------------------
by stof at 2012-05-26T10:20:23Z
@niklasf the new interface should be mentioned in the changelog of the Routing component
---------------------------------------------------------------------------
by travisbot at 2012-05-26T10:30:06Z
This pull request [fails](http://travis-ci.org/symfony/symfony/builds/1440837) (merged 34ea86a9 into 9e951991).
---------------------------------------------------------------------------
by niklasf at 2012-06-02T15:27:01Z
Ah ... so there were two pitfalls:
- PHPUnit clones the arguments of mocked functions. So they wouldn't equal.
- createGetResponseEventForUri() disables routing on purpose. So not using that helper, now.
Tests should be passing.
---------------------------------------------------------------------------
by travisbot at 2012-06-02T15:30:28Z
This pull request [passes](http://travis-ci.org/symfony/symfony/builds/1509054) (merged 7fab0118 into 1541fe26).
- The route compiler does not add extra space or line-feed,
- The generated regex does not use the 'x' modified any more,
- The PHP and apache matchers do not need to strip any chars (vs space and line feed before),
- The space characters are escaped according to the apache format
Commits
-------
e6e9b5a [Routing] Return the _route parameter from ApacheUrlMatcher
Discussion
----------
[Routing] Return the _route parameter from ApacheUrlMatcher
---------------------------------------------------------------------------
by fabpot at 2012-02-22T23:13:49Z
Can you squash your commits before I merge? Thanks.
---------------------------------------------------------------------------
by arnaud-lb at 2012-02-23T09:12:45Z
sure, done
Only + and % are now encoded in generated routes, since they are the only characters that, if not encoded, could cause problems/conflicts when decoded. Namely + turns into a space, and % followed by numbers could do funky things.
The matcher decodes everything which works since nothing will have %NN without being escaped, and + are escaped as well.
Commits
-------
49dd558 Couple more CS fixes
5a986bf Add $keysCount & minor CS fix
91f4097 [Routing] Better nesting for RouteCollections in dumped URL matcher classes With this change, a route prefixed with '/blogger' will be nested inside '/blog' (for example)
Discussion
----------
[Routing] Better nesting for RouteCollections in dumped URL matcher classes
Consider the following routing file:
_blog:
resource: "@AcmeDemoBundle/Resources/config/routing/BlogController.yml"
prefix: /blog
_blogger:
resource: "@AcmeDemoBundle/Resources/config/routing/BloggerController.yml"
prefix: /blogger
_bloggeroo:
resource: "@AcmeDemoBundle/Resources/config/routing/BloggerooController.yml"
prefix: /bloggeroo
_blogtest:
pattern: /blogtest
defaults: { _controller: AcmeDemoBundle:Blog:test }
login:
pattern: /login
defaults: { _controller: AcmeDemoBundle:Security:login }
Note: Each imported file contains two simple blog/blogger/bloggeroo routes (e.g. blog_index & blog_view)
With this change, the cached URL matcher looks something like this:
```php
<?php
class appprodUrlMatcher
{
public function match($pathinfo)
{
$allow = array();
if (0 === strpos($pathinfo, '/blog')) {
// blog_index
if (preg_match('#^/blog/(?P<slug>[^/]+?)$#x', $pathinfo, $matches)) {...}
// blog_view
if (preg_match('#^/blog/(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[^/]+?)$#x', $pathinfo, $matches)) {...}
if (0 === strpos($pathinfo, '/blogger')) {
// blogger_index
if (preg_match('#^/blogger/(?P<slug>[^/]+?)$#x', $pathinfo, $matches)) {...}
// blogger_view
if (preg_match('#^/blogger/(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[^/]+?)$#x', $pathinfo, $matches)) {...}
if (0 === strpos($pathinfo, '/bloggeroo')) {
// bloggeroo_index
if (preg_match('#^/bloggeroo/(?P<slug>[^/]+?)$#x', $pathinfo, $matches)) {...}
// bloggeroo_view
if (preg_match('#^/bloggeroo/(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[^/]+?)$#x', $pathinfo, $matches)) {...}
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
}
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
}
// _blogtest
if ($pathinfo === '/blogtest') {...}
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
}
// login
if ($pathinfo === '/login') {...}
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
}
}
```
As far as I can see, you can throw the 404 earlier (as I've done), as by nesting all these possibilities, there is no chance another route will be matched outside the parent if statement.
---------------------------------------------------------------------------
by stloyd at 2011/06/11 08:37:15 -0700
You should follow Symfony [CS rules] (http://symfony.com/doc/current/contributing/code/standards.html), also you should modify tests.
---------------------------------------------------------------------------
by lmcd at 2011/06/11 08:46:32 -0700
Besides the inline `continue` statement, I can't see spot any other CS violations. I'm on to the updated tests.
---------------------------------------------------------------------------
by fabpot at 2011/06/13 02:19:14 -0700
What if you have this:
_blog:
resource: "@AcmeDemoBundle/Resources/config/routing/BlogController.yml"
prefix: /blog
login:
pattern: /login
defaults: { _controller: AcmeDemoBundle:Security:login }
_blogger:
resource: "@AcmeDemoBundle/Resources/config/routing/BloggerController.yml"
prefix: /blogger
You cannot send 404 early because the same `blog` prefix is used in two different places. I can see many things that will break with this patch. I'm pretty sure we can enhance the performance of the existing code but let's do that after 2.0.
---------------------------------------------------------------------------
by lmcd at 2011/06/13 05:04:03 -0700
@fabpot: The code was designed so it would work in these kind of circumstances. I ran the dumper against the routing file you provided and this is the output below.
I see no reason why you can't throw the 404 earlier, as by nesting everything with similar prefixes, we're eliminating the possibility that a route will ever be matched outside of that if statement.
```php
public function match($pathinfo)
{
$allow = array();
if (0 === strpos($pathinfo, '/blog')) {
// blog_index
if (preg_match('#^/blog/(?P<slug>[^/]+?)$#x', $pathinfo, $matches)) {
...
}
// blog_view
if (preg_match('#^/blog/(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[^/]+?)$#x', $pathinfo, $matches)) {
...
}
if (0 === strpos($pathinfo, '/blogger')) {
// blog_index
if (preg_match('#^/blogger/(?P<slug>[^/]+?)$#x', $pathinfo, $matches)) {
...
}
// blog_view
if (preg_match('#^/blogger/(?P<year>\d{4})/(?P<month>\d{2})/(?P<slug>[^/]+?)$#x', $pathinfo, $matches)) {
...
}
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
}
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
}
// login
if ($pathinfo === '/login') {
...
}
throw 0 < count($allow) ? new MethodNotAllowedException(array_unique($allow)) : new ResourceNotFoundException();
}
```
---------------------------------------------------------------------------
by fabpot at 2011/06/13 07:48:49 -0700
Can you add some more tests to ensure that everything works fine and that we won't have regressions later on? Thanks.
* lmcd/master:
$code referenced but not defined in compileRoute()
[Routing] Optimised the PHP URL matcher dumper The cached URL matcher classes contain some unneeded logic. Consider the following example:
The cached URL matcher classes contain some unneeded logic. Consider the following example:
if (0 === strpos($pathinfo, '/Blog')) {
// blog_index
if (0 === strpos($pathinfo, '/Blog') && preg_match('#^/Blog/(?P<slug>[^/]+?)$#x', $pathinfo, $matches)) {
return array_merge($this->mergeDefaults($matches, array ( '_action' => 'index',)), array('_route' => 'blog_index'));
}
}
The 2nd strpos is not required, as we have already satisfied this condition in the parent if statement.
My change will produce the following code for the same routing setup::
if (0 === strpos($pathinfo, '/Blog')) {
// blog_index
if (preg_match('#^/Blog/(?P<slug>[^/]+?)$#x', $pathinfo, $matches)) {
return array_merge($this->mergeDefaults($matches, array ( '_action' => 'index',)), array('_route' => 'blog_index'));
}
}