php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #37854 Type Hinting with derived classes and interfaces not working
Submitted: 2006-06-19 22:11 UTC Modified: 2006-06-19 22:21 UTC
From: spam at codeword dot net Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: * OS: *
Private report: No CVE-ID:
 [2006-06-19 22:11 UTC] spam at codeword dot net
Description:
------------
When adding type hinting to an interface then implementing that interface using a derived class, the script compiler does not seem to recognise that the implemented type hint is derived from the interfaces type hint.  I hope that makes sense.  The code below may be more clear.

Reproduce code:
---------------
<?php
interface MyInterface{public function test(ClassA $object);}
class MyClass implements myInterface{
  public function test(ClassB $object){// should work but does not
    echo $object->x;
  }
}
class ClassA {public$x = "Class is ClassA";  }
class ClassB extends ClassA{  public $x = "Class is ClassB";}
$myclass = new MyClass;
$a = new ClassA;
$b = new ClassB;
$myclass->test($b);
$myclass->test($a);
?>

Expected result:
----------------
Class is ClassB
Fatal error: Argument 1 passed to MyClass::test() must be an instance of ClassB, called in typeHintTest.php on line 14 and defined in typeHintTest.php on line 4

Actual result:
--------------
Fatal error: Declaration of MyClass::test() must be compatible with that of MyInterface::test() in typeHintTest.php on line 3

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2006-06-19 22:21 UTC] helly@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

First we don't allow changesin the typhints in derived classes/implementing classes. Second you need to learn inheritance rules again. Your code would break is-a relation.
 [2012-04-20 10:39 UTC] kabanovdmitry at gmail dot com
Why then does PHP allow to narrow argument's type in subclass which extends base 
class?

This seems odd, because this violates Liskov Substitution Principle.
 [2013-10-14 12:07 UTC] worldoffame at hotmail dot com
Well this is indeed a bug, how can you say it is not just because you think it is not? Although changing typehinting should be disallowed for completely irrelevant classes, but narrowing down the scope of typehinting(changing from superclass/interface to subclasses) is generally enabled in most OO languages. Funny you are telling the bug reporter to learn inheritance, just by judging from that test example he/she wrote? 

Just like the last comment says, the current way PHP does is clearly violating Liskov Substitution Principle. There are so many things that work in other OO languages that do not work in PHP. Okay PHP is not java, but its not just java, its all the OO languages you can think of.
 [2013-10-14 12:25 UTC] nikic@php.net
@worldoffame: Please double-check your facts. PHP's typehint checks conform with LSP, see the first point on http://en.wikipedia.org/wiki/Liskov_substitution_principle: "Contravariance of method arguments in the subtype." This rule is respected by all mainstream languages. Only very few languages that explicitly denounce LSP support covariant method arguments, for example Eiffel. For more information see http://en.wikipedia.org/wiki/Covariance_and_contravariance_%28computer_science%29#Covariant_method_argument_type and the following section.
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Mon Apr 21 14:02:18 2014 UTC