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

Reply via email to