php – Is it a good idea to use interfaces to specify which magic methods a class will implement?

Question:

I've seen some code in PHP that, to check if a class has the __toString method, the method_exists function is used.

Example:

if (method_exists($object, '__toString')) echo $object;

On the other hand, I've seen interfaces that use the __toString method to force classes that implement it to have this method.

interface StringableInterface
{
     public function __toString();
}

if ($object instanceof StringableInterface) echo $object;

What are the advantages of using an interface that contains __toString , instead of just checking that this method exists in the class?

Answer:

Although both in many cases may seem to serve "almost" to the same effect, instanceof actually tries to inform if a certain class implements a certain interface, which is not the same as knowing if the method exists or not.

We can then put in a more careful performance analysis and as a result we can get interesting results, analyze the code I found and which in my opinion helps to understand…

interface HasMethod {
    public function myMethod();
}

class MyClass1 implements HasMethod {
    public function myMethod() {}
}

class MyClass2 {
    public function myMethod() {}
}

$myClass1 = new MyClass1();
$myClass2 = new MyClass2();

$times = [0,0,0];
$j = 0;
for($i = 0; $i < 100000; ++$i) {
    $start = microtime(1);
    ($myClass1 instanceof HasMethod) && $j++;
    $times[0] += microtime(1) - $start;

    $start = microtime(1);
    (method_exists($myClass1, 'myMethod')) && $j++;
    $times[1] += microtime(1) - $start;

    $start = microtime(1);
    (method_exists($myClass2, 'myMethod')) && $j++;
    $times[2] += microtime(1) - $start;
}

print_r($times);

Result:

Array
(
    [0] => 0.46121835708618 //instanceOf
    [1] => 0.53055930137634 //method_exists com interface
    [2] => 0.4961085319519  //method_exists sem interface
)

Using instanceof is slightly faster than method_exists() .

The speed advantage is particularly noticeable when I use an interface or the method doesn't exist.

I personally like using contracts as the interface better so I prefer instanceof as an "elegant solution".

To finish a question that in my opinion is very important and that sometimes fails many of us…

It is true that method_exists() returns the value of TRUE if the method exists. However, it also does this for private methods which can be problematic. For this there is also the is_callable() which in the example I indicated will return FALSE . I know it's a bit beyond the scope of the question, but I thought it was important to mention it!

Scroll to Top