-
Notifications
You must be signed in to change notification settings - Fork 13
PHP 7.1 - typehints, return types, strict types #41
PHP 7.1 - typehints, return types, strict types #41
Conversation
src/Route.php
Outdated
* @throws Exception\InvalidArgumentException for invalid path type. | ||
* @throws Exception\InvalidArgumentException for invalid middleware type. | ||
* @throws Exception\InvalidArgumentException for any invalid HTTP method names. | ||
*/ | ||
public function __construct($path, $middleware, $methods = self::HTTP_METHOD_ANY, $name = null) | ||
public function __construct(string $path, $middleware, $methods = self::HTTP_METHOD_ANY, string $name = null) |
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.
Would be nice if we could typehint on $middleware
and $methods
.
I've seen somewhere inconsistent with $methods
, I think in some place I've seen =null
which was translated later on to ANY
.
What with $middleware
. Is it not now just MiddlewareInterface
?
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.
I was just thinking about this myself when I reviewed your earlier patch, and just dove into how zend-expressive uses it.
At this point, within zend-expressive itself, we always pass a middleware instance, as Application::prepareMiddleware()
creates an instance based on the argument passed to Application::route()
. As such, I think we could likely update this to have a typehint.
We cannot typehint $methods
currently, as it can be either an array of HTTP method names or the HTTP_METHOD_ANY
constant, which is an integer. I did it this way as the HTTP specification allows arbitrary method names, so there's no way to create a "master list" representing all methods.
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.
Updated to MiddlewareInterface
typehint on $middleware
.
About $methods
, please see:
https://github.com/zendframework/zend-expressive/pull/530/files#diff-c9248b3167fc44af085b81db2e292837R283
So there we have array $methods = null
and then we have:
$methods = null === $methods ? Router\Route::HTTP_METHOD_ANY : $methods;
Maybe we should do the same?
I'm not sure if I like this behaviour (null
means any, array defines method explicitly, so emoty array means none).
Similar solution we have on mocking in PHPUnit - setMethods()
- we can pass null|array
and it has different behaviour with null
and empty array.
I would prefer to have it consistent - the same in expressive and expressive-router.
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.
Nullable would work here, I guess; we'd have to change the value of the constant to be null
, however, to ensure there's no breakage for folks who use the constant to specify the value. That would allow ?array $methods = null
in the signature.
test/RouteResultTest.php
Outdated
@@ -45,7 +46,7 @@ public function testRouteFailureRetrieveAllHttpMethods() | |||
public function testRouteFailureRetrieveHttpMethods() | |||
{ | |||
$result = RouteResult::fromRouteFailure(); | |||
$this->assertSame([], $result->getAllowedMethods()); | |||
$this->assertSame(['*'], $result->getAllowedMethods()); |
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.
Behaviour here has been changed, we can set default value to []
and typehint on ?array
in fromRouteFailure
method to keep the previous functionality.
@weierophinney What do you think?
I'd keep it consistent.
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.
We need to make sure that the consumers (the individual routing libraries) are able to upgrade without issue. So long as the same argument types are accepted, how the default works is less important.
That said, []
seems VERY DIFFERENT than ['*']
; the first looks like an empty set (no HTTP methods specified), while the latter looks like it accepts a "wildcard" (i.e., any method).
I think in this case, we need to look at the RouteMiddleware
in Expressive to determine what it expects.
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.
I can't see any usages of fromRouteFailure
method in Expressive.
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.
Look in the individual routers, then; just looked, and the FastRouter bridge definitely calls it.
It is changed to keep the previous functionality, defailt value (mow empty array) will set allowed methods to none
`null` value is no longer possible
* @throws Exception\RuntimeException when called after match() or | ||
* generateUri() have been called. | ||
*/ | ||
public function addRoute(Route $route); | ||
public function addRoute(Route $route) : void; |
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.
Ooof. The signature changes in this interface will require new major versions of each router unless we update them to have return values now (return types are covariant, so an implementation can define a more specific return type).
I'll experiment with that momentarily on the zendrouter repo.
* @throws Exception\RuntimeException if unable to generate the given URI. | ||
*/ | ||
public function generateUri($name, array $substitutions = [], array $options = []); | ||
public function generateUri(string $name, array $substitutions = [], array $options = []) : string; |
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.
And this one requires a major version bump, as the typehint of an argument has changed.
I think we should limit the changes in this interface to return value typehints for now, as it will result in fewer moving parts with regards to coordinating releases.
We can revisit after we have all the various repos updated.
As we allow bind only MiddlewareInterface the method will return only MiddlewareInterface instances
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.
Per a conversation on Slack, we agreed that adding the typehints to the interface makes sense, as it solidifies and makes explicit the contract by which implementations must abide. This will, of course, require major-version bumps in each implementation.
.docheader
Outdated
@@ -3,3 +3,4 @@ | |||
* @copyright Copyright (c) %regexp:(20\d{2}-)?20\d{2}% Zend Technologies USA Inc. (http://www.zend.com) | |||
* @license https://github.com/zendframework/zend-expressive-router/blob/master/LICENSE.md New BSD License | |||
*/ | |||
declare(strict_types=1); |
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.
IIRC, we need one empty line between the file-level docblock and any directives, per PSR-12. I'll update those when I merge.
Merged to release-3.0.0 branch; not sure why it didn't auto-close. |
No description provided.