php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #42330 Type hinting based upon interfaces not working
Submitted: 2007-08-17 17:31 UTC Modified: 2007-08-17 18:16 UTC
Votes:6
Avg. Score:4.3 ± 1.5
Reproduced:5 of 6 (83.3%)
Same Version:2 (40.0%)
Same OS:3 (60.0%)
From: udo dot rader at bestsolution dot at Assigned:
Status: Wont fix Package: Scripting Engine problem
PHP Version: 5.2.3 OS: Linux
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2007-08-17 17:31 UTC] udo dot rader at bestsolution dot at
Description:
------------
When using type hinting with interfaces it fails to recognoize classes implementing the interface as "compatible".

Reproduce code:
---------------
abstract class Foo  {
    abstract public function saySomething( IBar $what );
    abstract public function saySomethingElse( IBar $what );
}
class BarDAO extends Foo {
    function saySomething( IBar $what ) {
        echo $what->getMessage();
    }
    function saySomethingElse( BarTransfer $what ) {
        echo $what->getMessage();
    }
}
interface IBar {
    function getMessage();
}
class BarTransfer implements IBar {
    function getMessage() {
        return "Hello from BarTransfer";
    }
}
$barDAO = new BarDAO();
$barTransfer = new BarTransfer();
$barDAO->saySomething( $barTransfer );
$barDAO->saySomethingElse( $barTransfer );


Expected result:
----------------
The expected result should be that no compiler error occurs and that the script runs.

Actual result:
--------------
The PHP interpreter gives this error:

Fatal error: Declaration of BarDAO::saySomethingElse() must be compatible with that of Foo::saySomethingElse()

But, IMHO, BarTransfer can hardly be more "compatible" with IBar.


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2007-08-17 17:47 UTC] derick@php.net
PHP does not implement inheritance checks for typehinted arguments. Please also refer to the PDM meeting notes, where this was discussed: http://www.php.net/~derick/meeting-notes.html#implement-inheritance-rules-for-type-hints
 [2007-08-17 18:16 UTC] udo dot rader at bestsolution dot at
Hmm, too bad.

The link you provided about the PDM meeting says "that most probably no language currently implements this correctly" is not true. 

Java for instance does this just nicely at least since 1.3.

With that limitation, the implementation of an AbstractDAO/AbstractFactory pattern will fail if type hinting is wanted, because transfer objects need to be identifyable by their common interface. Otherwise the entire interface thing in PHP does not make much sense, IMHO.

So anyhow, at least the error message should be changed to be more clear.
 [2012-08-16 14:13 UTC] jsuprock at gmail dot com
Hi Derek,

    Thank you for your responses; I ran into this same issue.  I hate to 
resurrect old tickets, but are you sure you want to leave this out?  

    Here is my concern...  There is no point to have type hinting if object 
inheritance is not respected.  For example, let's say I have the following 
interface...

interface Comparable
{
    public function gte(Comparable $value);
    public function lte(Comparable $value);
    public function eq(Comparable $value);
    public function gt(Comparable $value);
    public function lt(Comparable $value);
}

and now I have the following base classes...

class Orange implements Comparable
{
    ...
    public function gte(Comparable $orange) { ... }
    public function lte(Comparable $orange) { ... }
    public function eq(Comparable $orange) { ... }
    public function gt(Comparable $orange) { ... }
    public function lt(Comparable $orange) { ... }
}

class Apple implements Comparable
{
    ...
    public function gte(Comparable $apple) { ... }
    public function lte(Comparable $apple) { ... }
    public function eq(Comparable $apple) { ... }
    public function gt(Comparable $apple) { ... }
    public function lt(Comparable $apple) { ... }
}

Does it REALLY make sense to compare Apples to Oranges???


Kind regards,

John
 [2012-08-16 14:15 UTC] jsuprock at gmail dot com
Derick,

  I'm sorry I misspelled your name.

Sincerely,

John S
 [2014-09-17 15:47 UTC] login dot naitsirch at arcor dot de
Here's an example that shows, why this is not allowed:

<?php
class AnotherBar implements IBar
{
    function getMessage() { }
}

function moo(Foo $foo)
{
    $bar = new AnotherBar();
    $foo->saySomethingElse($bar);
}

moo(new BarDAO());

This would be a syntactically valid code, but it would fail, because BarDAO::saySomethingElse() does not allow AnotherBar.

It is complicated, but it is easier to understand, if you see an example.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Fri Apr 19 10:01:28 2024 UTC