On 12/05/2016 19:02, Rowan Collins wrote:
On 12/05/2016 17:47, Andreas Heigl wrote:
It's the other way around.
The interface creates a contract that ensures that you can use ALL
methods available in your SpecialClass.
I don't think that's what the interface in the example means:
interface Foo
{
public function foo(SpecialClass $object);
}
What this says is "an object adhering to interface Foo has a method
foo which accepts any SpecialClass instance".
In other words, it says that the following is bound to succeed:
if ( $thing instanceOf Foo ) {
$thing->foo( new SpecialClass );
}
Marco is right that a class with a wider definition fulfils this
contract:
class Bar implements Foo
{
public function foo(BaseClass $object)
{
// do something with BaseClass $object
}
}
$thing = new Bar;
if ( $thing instanceOf Foo ) {
$thing->foo( new SpecialClass );
}
This is called "contravariance of parameters", and has come up a
couple of times on the list. In particular, when return types were
added, it was discussed that they should technically be covariant
(subtypes can
"narrow" return types, and say they only return a specific sub-type of
the original contract).
So from a design point of view, there is no reason not to support it;
unfortunately, there are some technical hurdles to implementing that
within the PHP engine. Here is a nice summary from Anthony Ferrara:
http://marc.info/?l=php-internals&m=142791636808421&w=2
Regards,
Thanks Rowan for your response and for the link, very interesting.
Adding a bit of context to my question, I asked it after following a
discussion in the FIG mailing list.
In PSR-7 you have a RequestInterface and a ServerRequestInterface with
inherits from it (the BaseClass and SpecialClass of my example).
Now there is a discussion on how to standardize a MiddlewareInterface.
You would like to have an interface like
interface ServerMiddlewareInterface
{
public function __invoke(ServerRequestInterface $request, ...)
}
which plays the role of Foo, and maybe an implementation
class MyMiddleware
{
public function __invoke(RequestInterface $request, ...)
{
// do something with $request
}
}
which plays the part of Bar.
Since at the moment Bar can not implement Foo, the solution to this is,
from a design point of view, a bit akward (see
https://github.com/php-fig/fig-standards/blob/95aece5e68376e9a5d79d2385d755824dfac3ed8/proposed/middleware.md#21-server-vs-client-requests
for details). It would be nice if "variant" parameters and return types
were introduced, so the design could be improved (this is just an
example, I guess there could be more aroud).
Regards
marco
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php