Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP trait: is there a proper way to ensure that class using a trait extends a super class which contains certain method?

Example #2 from PHP manual http://php.net/manual/en/language.oop5.traits.php states

<?php
class Base {
    public function sayHello() {
        echo 'Hello ';
    }
}

trait SayWorld {
    public function sayHello() {
        parent::sayHello();
        echo 'World!';
    }
}

class MyHelloWorld extends Base {
    use SayWorld;
}

$o = new MyHelloWorld();
$o->sayHello();
?>

This is correct code, but it's not safe to use parent:: in that context. Let's say I wrote my own 'hello world' class which does not inherit any other classes:

<?php
class MyOwnHelloWorld
{
    use SayWorld;
}
?>

This code will not produce any errors until I call the sayHello() method. This is bad.

On the other hand if the trait needs to use a certain method I can write this method as abstract, and this is good as it ensures that the trait is correctly used at compile time. But this does not apply to parent classes:

<?php
trait SayWorld
{
    public function sayHelloWorld()
    {
        $this->sayHello();
        echo 'World!';
    }

    public abstract function sayHello(); // compile-time safety

}

So my question is: Is there a way to ensure (at compile time, not at runtime) that class which uses a certain trait will have parent::sayHello() method?

like image 821
Maciej Sz Avatar asked Oct 21 '12 21:10

Maciej Sz


1 Answers

No, there is not. In fact, this example is very bad, since the purpose of introducing traits was to introduce same functionality to many classes without relying on inheritance, and using parent not only requires class to have parent, but also it should have specific method.

On a side note, parent calls are not checked at the compile time, you can define simple class that does not extend anything with parent calls in it's methods, ant it will work until one of these method is called.

like image 92
dev-null-dweller Avatar answered Sep 19 '22 22:09

dev-null-dweller