FUDforum
Fast Uncompromising Discussions. FUDforum will get your users talking.

Home » Imported messages » comp.lang.php » Strange but true! Working with interfaces in PHP
Show: Today's Messages :: Polls :: Message Navigator
Return to the default flat view Create a new topic Submit Reply
Re: Strange but true! Working with interfaces in PHP [message #185480 is a reply to message #185450] Thu, 03 April 2014 11:20 Go to previous messageGo to previous message
Christoph Michael Bec is currently offline  Christoph Michael Bec
Messages: 207
Registered: June 2013
Karma:
Senior Member
Mirco wrote:

> I was working on a software of arbitrary complexity when I stumbled
> upon this strange behavior of the PHP compiler.
>
> Problem: I have these interfaces and classes:
>
> [code sample]
>
> Running the above code, this is what I get: Fatal error: Declaration
> of B::match() must be compatible with that of IBaseB::match()

Confirmed on PHP 5.5.11.

> This behavior is very odd, because A implements IA that extends from
> IBaseA. So IA is an interface of type IBaseA. Methods I will put in
> IBaseA will be also in IA. Class B accepts, in the match() method, an
> instance of IA. Class B extends from IBaseB that in turn accepts an
> instance of IBaseA.
>
> B should accept IA. In fact the interface that B implements accepts a
> more specific version of IA, but the Fatal Error still pops up.

What you are assuming here is that type hints support covariance.
However, current PHP supports only invariance reliably. Consider the
following example:

class A {}
class B extends A {}
class C {function foo(A $var) {}}
class D extends C {function foo(B $var) {}}

The last line gives the following notice:

Strict standards: Declaration of D::foo() should be compatible with
C::foo(A $var)

It would be nice, if PHP accepts covariant type hints for function
parameters, but not doing it is not a bug. In this case it might be a
documentation bug, or rather a documentation omission -- at least I was
not able to find this behavior documented.

> The things become more strange if we look at another example. This
> one:
>
> [code sample]
>
> Here, what I get it's not a Fatal Error, but a Catchable Fatal
> Error.

PHP 5.5.11 gives:

Catchable fatal error: Argument 1 passed to B::match() must implement
interface IA, instance of A given

> This is an error that could be catched by this simple
> function:
>
> [error handler sample]
>
> This time though, the compiler should not let me continue with the
> execution because:
>
> B implements IB that extends from IBaseB. IBaseB accepts instances of
> IA. IA extends from IBaseA. A implements IBaseA.
>
> What i'm passing to the match() method of B is an instance of A, that
> is more strict that IA. The compiler should throw a Fatal Error and
> it shouldn't let me continue with the execution! The inner details of
> B's match() implementation require an instance of IA with its own
> specific methods that could not be provided by IA's father, IBaseA.

One might argue whether a Fatal Error is more appropriate here. After
all PHP is a dynamically typed language, and what is given here is only
a type *hint*, not a type declaration. In this case the program *could*
run without errors, because the $subject parameter is not used by the
function, and even if it was used, that doesn't necessarily imply that
the argument $a would be "incompatible". So a Catchable Fatal Error
might be more inline with PHP's dynamic typing.

PS: Please avoid overlong lines, because Google Groups can't properly
handle them.

--
Christoph M. Becker
[Message index]
 
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Read Message
Previous Topic: Need help accessing the key array.
Next Topic: MYSQL PHP Query Not Working
Goto Forum:
  

-=] Back to Top [=-
[ Syndicate this forum (XML) ] [ RSS ]

Current Time: Sat Nov 23 21:34:57 GMT 2024

Total time taken to generate the page: 0.03929 seconds