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

Asked

Viewed 62 times

3

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

Example:

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

On the other hand, I have seen interfaces using the method __toString to force the implementing classes to have this method.

interface StringableInterface
{
     public function __toString();
}

if ($object instanceof StringableInterface) echo $object;

What are the advantages of using a interface that contains __toString, instead of using only the verification that this method exists in the class?

1 answer

2

Although both in many cases may seem to serve "almost" for the same effect in fact the instanceof seeks to inform whether a particular class implements a particular interface, which is not the same as knowing whether the method exists or not.

We can then put a more careful analysis on the performance and as a result we can get interesting results, analyze the code I found and 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);

Upshot:

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

Use the instanceof is slightly faster than method_exists().

The advantage of speed is particularly visible when using an interface or method does not exist.

I personally like more to use contracts as the interface so I prefer the instanceof as "elegant solution".

To conclude a question which in my opinion is very important and which sometimes fails many of us...

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

  • Enlightening, especially the question of method_exists detect the private. I had forgotten that detail. It makes all the difference yes

Browser other questions tagged

You are not signed in. Login or sign up in order to post.