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
Fix possibility extends #158
Conversation
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.
ready
28a8fb0
to
73726b5
Compare
Hi @ilyar, PSR-7 doesn't define a constructor in |
@jeskew I agree, but this is already the responsibility of the project. Trying to use your implementation, I encountered the difficulties of extension. Maybe I want the wrong... I had doubts in the current decision and I was researching the topic, I found the same solution in an alternate implementation PSR7 (https://github.com/slimphp/Slim-Psr7/blob/8814eb071ce04239eaaa3af18f35d90fff62e9ae/src/Request.php#L146). |
I'm 👎 for introducing late static binding. The ServerRequest should be considered as a value object and you should never have the need to extend it. (Ie the code should not be written with worse performance just to allow you to extend it) |
Just wanted to weigh in here, since I created a duplicate bug report and fix over in #159 . To the first point, re To the second point, re "value object": This is a shortsighted and arbitrary argument that rests solely on the validity (or not) of your own vision for how the implementation should be used. One of the major advantages of OOP is that I don't have to copy-paste all the good work you've done to add functionality that I need for my application. As it stands, my options are limited to finding a different implementation (which is more wasteful of human resources in the open source community than using late static binding would be of machine resources), or to using my own fork of your implementation, which is also wasteful (and annoying). Please reconsider pulling this fix. |
} | ||
} | ||
|
||
class FooExtend extends ServerRequest |
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.
@ilyar Thanks for creating this fix, and thanks especially for creating a test case, which is something I forgot to do in mine :).
Just wanted to share an opinion: To me, it seems better to define FooExtend
in a separate file. I often do this by using a classes
folder under tests
, namespacing those classes with Test
, and then including them in the autoload-dev
section of the composer file. The modified composer.json
might look like this:
....
"files": ["src/functions_include.php"]
},
"autoload-dev": {
"psr-4": {
"\\Test": "tests/classes/"
}
},
"extra": {
....
Then you can use the class in any test by calling \Test\FooExtend
.
Anyway, take it or leave it!
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.
@kael-shipman Maybe it would be appropriate to call it so GuzzleHttp\Tests\Fixture\FooExtend
?
And accordingly place tests\Fixture\FooExtend.php
.
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 could work, though I always thought of Fixtures as predictable data states (i.e., NOT just classes meant to test functionality of other classes).
My vote is to make the namespace \GuzzleHttp\Test
. That would keep it simple and also allow them to possibly break that set of test classes out into a separate repo if they start using them across multiple sub-projects (something I do occasionally).
Anyway, your call!
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.
fix
@kael-shipman That's not true at all. A subclass can overwrite the constructor in any way it wants. I can change the order of arguments, remove argument and just call the parent constructor with different stuff. So I agree with @Nyholm that using late static binging here is technically not correct and unsafe to do. If you really need a subclass, you can just do something like |
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.
Different implementatin via Request::fromPsr7
TL;DR
@Tobion Ok, I concede that another programmer can redefine the constructor arbitrarily. I was convinced otherwise because I'm usually coding against interfaces, which, as others have noted, this constructor is not bound by. (I didn't realize that method signature verification only applied when implementing interfaces and not when subclassing.) Still, I strongly believe late static binding in When I subclassed your class, the first thing I did was make sure that any methods I overrode (including The second thing I did was try to instantiate my new subclass using the Now, consider what would happen if we implemented the Even more than that, if you'll forgive my saying so, it's ugly. Would you rather type, Now consider simply implementing late static binding. In the event that someone subclasses responsibly, everything works as expected. No errors, no debugging, no duplicate bug reports, no bikeshedding. In the event that someone changes your arguments and tries to use Conclusion As you can see, the costs of implementing LSB in The costs of taking a different approach are increased code and documentation maintenance and continued engagement with other programmers as they continue to run into what honestly looks like a bug and request that it be fixed, not to mention a proliferation of forks that makes the landscape confusing. Please -- please -- consider incorporating this change. It costs you nothing. Thanks, |
public function testExtend() | ||
{ | ||
$actual = FooExtend::fromGlobals(); | ||
$this->assertInstanceOf('GuzzleHttp\\Tests\\Psr7\\FooExtend', $actual); |
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.
This can be written in an cleaner way, as assertInstanceOf(FooExtend::class, $actual)
.
This avoids needing to manually resolve namespace paths or escape characters.
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.
done
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.
@Krinkle it is possible, because support php5.4 https://travis-ci.org/guzzle/psr7/builds/349217118
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.
Hmm... I see. I wasn’t expecting PHP 5.4 support here in the master branch. The oldest is expect at this point is PHP 5.6, or, of supporting current oldstable Debian, maybe PHP 5.5.
Thanks for considering! Maybe another time.
fef0761
to
5ba86f9
Compare
5ba86f9
to
eb630f1
Compare
I'm pretty confident that I will propose making all message classes in this project final if we ever hit a 2.0 version. Reason: HTTP messages are represented as value objects, implementing an interface. From this point I don't see any valid use cases for extending the message classes. So for now, I'm rejecting this change. |
Thank you for your explanations. |
No description provided.