Why do I receive this error:
Fatal error: Declaration of ConcreteFooMapper::load() must be compatible with that of AbstractFooMapper::load() on line 18
from this code:
<?php
interface Foo {
public function foo();
}
class ConcreteFoo implements Foo {
public function foo() {
}
}
abstract class AbstractFooMapper {
abstract public function load(Foo $entity, array $data);
}
class ConcreteFooMapper extends AbstractFooMapper {
public function load(ConcreteFoo $entity, array $data) {
}
}
?>
My initial thought is that it's a bug; PHP isn't detecting that ConcreteFoo implements Foo when it is evaluating the method declaration it. I think this because when you run this code:
<?php
interface Foo {
public function foo();
}
class ConcreteFoo implements Foo {
public function foo() {
}
}
$foo = new ConcreteFoo();
if ($foo instanceof Foo)
{
print 'w00t!';
}
else
{
print 'FAIL!';
}
?>
it prints w00t! indicating ConcreteFoo is an instance of Foo.
Any insights into whether this behavior is correct or not?
According to the docs, type hints must match exactly.
The class implementing the interface must use the exact same method signatures as are defined in the interface. Not doing so will result in a fatal error. And same rules for classes which extends abstract classes.
Please, see in see in details here, see here too
And this is right behaviour \ logic.
check here Abstract types are useful in that they can be used to define and enforce a protocol; a set of operations which all objects that implement the protocol must support.
if we assume that your code will work without exception, then we have following problem: ConcreteFooMapper
can't use instances of some class ConcreteFoo2 implements Foo
as parameter for load
method, but should (by Abstract class definition)
Also, if you use same signature, it not a problem really, cause all class \ type info available. Please, check following code
<?php
interface Foo {
public function foo();
}
class ConcreteFoo implements Foo {
public function foo() {
}
}
abstract class AbstractFooMapper {
abstract public function load(Foo $entity, array $data);
}
class ConcreteFooMapper extends AbstractFooMapper {
public function load(Foo $entity, array $data) {
var_dump($entity instanceof Foo);
var_dump($entity instanceof ConcreteFoo);
}
}
$someConcreteFoo = new ConcreteFoo();
$someFooMapper = new ConcreteFooMapper();
$someFooMapper->load($someConcreteFoo, array('somekey' => 'somevalue'));
// output
// bool(true) bool(true)
?>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With