-
-
Save andriesss/6590912 to your computer and use it in GitHub Desktop.
<?php | |
interface Comparable { | |
function compare(self $compare); | |
} | |
class Foo implements Comparable { | |
function compare(self $compare) {} | |
} | |
class Bar implements Comparable { | |
function compare(self $compare) {} | |
} | |
$foo = new Foo(); | |
$bar = new Bar(); | |
$foo->compare($foo); | |
$bar->compare($bar); |
PHP Fatal error: Declaration of Foo::compare() must be compatible with Comparable::compare(Comparable $compare) in /Users/patrick/test.php on line 7
When I replace 'self' in line 7 and 11 with 'Comparable' it works again. It seems that the 'self' in the interface is resolved to Comparable and the class method signatures are being literally compared to that.
This does sound like a bug to me.
I can only say: avoid using 'self' in signatures in the first place... :)
Well, changing the type hint to "Comparable" is not what I need. I'd like to define in the interface, that a method of an implementing class can only accept an instance of itself (the implementing class). This seems no longer possible as of PHP 5.4.1... :(
@andriess I think the interface works fine:
<?php
interface Comparable {
function compare(self $compare);
}
class Foo implements Comparable {
function compare(Comparable $compare) {}
}
class Bar implements Comparable {
function compare(Comparable $compare) {}
}
$foo = new Foo();
$bar = new Bar();
$foo->compare($foo);
$bar->compare($bar);
@Ocramius, now the method accepts any class that implements the comparible interface. I want to define that a method can only accept an instance of itself.
@andriesss that could work with the static
keyword (unsupported), but is still wrong.
Pretty lame, seems like a nice feature, I guess.
@andriesss the fact is that every implementation basically accepts different types of objects. That's a mess from a LSP pov
@Ocramius, the only option I have is:
<?php
interface Comparable {
function compare(Comparable $compare);
}
class Foo implements Comparable {
function compare(Comparable $compare) {
if (!$compare instanceof self) {
throw new \InvalidArgumentException('sometimes php sucks a little');
}
}
}
class Bar implements Comparable {
function compare(Comparable $compare) {
if (!$compare instanceof self) {
throw new \InvalidArgumentException('sometimes php sucks a little');
}
}
}
$foo = new Foo();
$bar = new Bar();
$foo->compare($foo);
$bar->compare($bar);
@andriesss that's about right... Again, I don't think that's a PHP issue.
This works up to PHP version 5.3.19, but it seems that it no longer works for PHP 5.4.X. I have found this: https://bugs.php.net/bug.php?id=60573, but i'm not sure what the outcome of it is.