-
-
Notifications
You must be signed in to change notification settings - Fork 9.6k
[RFC][Routing] made RequestContext optional in generator and matcher #5895
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
Conversation
{ | ||
$this->routes = $routes; | ||
$this->context = $context; | ||
if ($context instanceof Request) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does it trigger autoloading? If so it would make HttpFoundation a required dependency. But the condition can be switched, so is not required.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instanceof does not trigger autoloading.
On Fri, Nov 2, 2012 at 1:40 PM, Tobias Schultze notifications@github.comwrote:
In src/Symfony/Component/Routing/Generator/UrlGenerator.php:
{ $this->routes = $routes;
$this->context = $context;
if ($context instanceof Request) {
Does it trigger autoloading? If so it would make HttpFoundation a required
dependency. But the condition can be switched, so it isn't.—
Reply to this email directly or view it on GitHubhttps://github.com//pull/5895/files#r2015580.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok thanks for the info
you probably need to check the RouterListener to add some |
* @param Request $request The request to match | ||
* @see UrlMatcherInterface | ||
* | ||
* @param Request|string $request A Request or a string with the path component of a URL (raw format, i.e. not urldecoded). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's better to say, that RequestMatcherInterface only need to support Request and not necessarily a path string, so they don't need to deal with that case. So UrlMatcherInterface need only support string and RequestMatcherInterface need only support Request.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Tobion you cannot do it. This PR makes it extend UrlMatcherInterface so it has to respect the contract of the UrlMatcherInterface otherwise it is simply broken.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah thought about that too. and it also makes sense that RequestMatcherInterface extends UrlMatcherInterface as the path is a component of a request. so it shouldnt be a problem.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A request-centric matcher can easily turn a path string into a request by creating a new Request object, which would then behave identically for the rest of the method. I think it's fine to require supporting both.
if (null !== $this->context) { | ||
$mergedParams = array_replace($defaults, $this->context->getParameters(), $parameters); | ||
} else { | ||
$mergedParams = array_replace($defaults, $parameters); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That makes me think that when not using a RequestContext, there is no way to define global default parameters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true. It's mostly used for the _locale
. For this we can use Request::getLocale()
as default parameter for a _locale
placeholder. This is then equivalent to the HttpKernel/EventListener/LocaleListener but for a Request object.
Overall, this PR looks ok to me. @Tobion I see that you have some todo items in the PR description, can you fix thembefore I merge? |
@Tobion Anything left before I merge this PR? |
#3958 has been merged now. |
Any chance you can finish this soon. Changes like this one need to be merged before the end of this week. |
So the usage of RequestContext is now optional everywhere because people can use a Request directly instead. For this to achieve, the generator and matcher interface is now independent from RequestContextAwareInterface and the RequestMatcherInterface now extends the UrlMatcherInterface.
This is because if no RequestContext is set before calling get, there is no context that could be returned.
it also fixes the type hints that didnt make much sense
Unfortunately this is not allowed in PHP5.3 which we support, so we cannot override the phpdoc for the method either
Hm this is quite some work because I would also need to make TraceableUrlMatcher, RedirectableUrlMatcher and ApacheUrlMatcher work with a Request object. Also many test would be necessary theoretically to cover all. Also I'm not quite happy with it in general. Having UrlGenerator implement both So instead of the current approach I'd like to suggest a different one: @fabpot what do you think? |
Theoretically, I do like the idea of having the context as a RequestContent object or a Request object. Now, let's see of the code looks like with this change. |
@Tobion: any update on this PR? Can we close it and open a ticket for the suggestion in your last comment instead? |
@@ -56,7 +56,7 @@ public function __construct($baseUrl = '', $method = 'GET', $host = 'localhost', | |||
$this->scheme = strtolower($scheme); | |||
$this->httpPort = $httpPort; | |||
$this->httpsPort = $httpsPort; | |||
$this->pathInfo = $path; | |||
$this->pathInfo = $pathinfo; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Casing should be consistent here.
I'd leave it open because I would also work on the new implement in this PR when I find some time. And the PR motivation description remains the same. |
Is it worth working on this at this point? Especially as we won't break BC anymore. |
Closing this PR as the code is not finished. I've opened an issue to keep track of this possible change (see 8C28 #8705). |
tests pass: yes
bc break: yes but only tiny and none for the symfony implementations.
todo:
After discussion with @Crell, we agreed that the RequestContext is a burden in reusing the routing component. That's because it only duplicates information of the Request and is not really useful without it anyway. Since we probably cannot remove it fully as it would be a big BC break, my idea is to make it optional. So the symfony generator and matcher both work with a RequestContext and a Request. I removed the RequestContextAwareInterface from the interfaces so a custom router does not need a RequestContext anymore. The default symfony generator/matcher still implements RequestContextAwareInterface but can also work with a Request. So
UrlMatcher::match(Request)
is now also possible. And the generator can useUrlGenerator::setRequest()
instead ofsetContext()
.I think it makes the routing more useable in symfony and more reusable for other libraries.
And it will probably make it easier to integrate content negotiation as matching a request directly with all it's metadata (like Accept header) is now possible.
One more point: symfony allowed to use matching a Request with #4363. But it's not integrated in symfony as symfonys router does not use it at all. And the important interfaces like the RouterInterface required the RequestContext anyway. So there was no way to use Request matching without RequestContext. This PR replaces the other extension point.
The only bc break is in terms of interfaces. People should be aware that RequestContextAwareInterface is not part of UrlGeneratorInterface/UrlMatcherInterface/RouterInterface anymore. And the RequestMatcherInterface was changed.