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

3

I've seen some PHP code 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 have 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 a interface that contains __toString , instead of just checking that this method exists in the class?

    
asked by anonymous 10.09.2015 / 17:42

1 answer

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

We can then put a more careful analysis of the performance and as a result we can get interesting results, analyze the code that I found and that in my opinion helps to realize ...

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 advantage of speed is particularly noticeable when using an interface or the method does not exist.

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

To end an issue that in my opinion is very important and sometimes fails many of us ...

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

    
11.09.2015 / 11:44