Exakat 0.11.5 is out, right after the excellent Darkmira Tour Brazil. Although it delayed the Monday publication, it also gave a list of good ideas and some time in the airport to work on it. So, this version is featuring a new report, called ‘Dependency wheel’, and four new analysis: Avoid typehinting with classes, Could typehint, Implemented methods must be public, and no references on left. And some foundation work on the engine, and more updated analysis. It’s time for the exakat 0.11.5 review.
Avoid Typehinting with classes
Typehinting adds a check on incoming or outgoing data. It may be done with a class or an interface. The best way to do it is to use interfaces: this open the possibility to replace entirely the current class by a refactored version. The interface then guarantees that the new class has the right methods. On the other hand, using class as typehint means subclassing it to replace it.
This analysis report any class used as typehint, and suggest to create an interface instead.
<?php // Typehint with a class. class x { function foo(x $x) {} } // This is a replacement for the above class x2018 extends x { function foo(xInterface $x) {} } // Typehint with an interface interface xInterface { function foo(x $x); } class x implements xInterface { function foo(xInterface $x) {} } // This is a replacement for the above class x2018 implements xInterface { function foo(xInterface $x) {} } ?>
Could typehint
This analysis searches methods for usage of ‘instanceof’ and suggest using the compared class as a typehint. Usually, this leads to shorter code and more systematic check upon arguments. This analysis is still a be harsh, and may produce false positive when various types are used inside the same method. It still may be a good idea to split this method.
<?php function foo($x) { if (!$x instanceof MyObject) { return false; } // do something } function bar(MyObject $x) { // do something } ?>
Implemented methods must be public
Another instance of code that lints but never execute: implemented methods must be public in the implementing class. This is reported when the code is executed, even if the class is not instantiated.
<?php class x implements i { private function foo() {} } interface i { function foo(); } ?>
The error message is actually quite confusing:
Fatal error: Access level to x::foo() must be public (as in class i) in file.php on line 3
No references on left
This analysis spot a rare condition on PHP:
<?php $a = 1; $b = 2; $c = $a + $b; // $c === 5 $c = &$a + $b; // $c === $a === 1 $c = $a + &$b; // Fatal error ?>
The adjunction of & makes the precedence of the assignation higher than the addition, leading to a lost addition, and the assignation of a reference. Lines 3 and 4 look very similar, but behave very distinctly.
I don’t expect to find too many issues with this analysis. It is simply good to know that Exakat also has your back on rare issues.
Dependency wheel
After last week work on ‘Code flower’, the new report is based on another work from Francois Zaninotto: Dependency wheel. This report presents all the classes in a circle, and link each of them whenever there is an extends or implements definition. Traits and use are coming up in a next iteration. This makes a great visualization for the classes and complexity.
The wheel is dynamic: you may search for a specific class using the classic search function, and when hovering on a class, the wheel reveals the linked classes or interfaces. The link is large when the link is large when it starts, and small when it arrives, indicating the orientation of the relation. Colors are arbitrary and do not carry any meaning. A dummy ‘class’ called ‘Main’ has been added to support all classes that are not extending anything.
Such wheel is interesting to use when refactoring a class: you have good visibility over the dependencies to the class.
This visualization may be the base for other relations inside the code: stay tuned for more in the coming weeks.
Happy PHP code reviews
Exakat 0.11.5 keeps adding more insights to the reports. This week, we got help from the Darkmira Tour : Thanks to the Brazilian community! And to Francois Zaninotto for your contributions. Apply this new visualization to your code and tell us what you learnt from them @exakat.
All the 320+ analyzers are presented in the docs, including the frustrating ‘Failed Substr Comparaison‘ that reports when subtr($x, 0, 4) are compared to a string with a different length (say ‘1234567’). Download Exakat on exakat.io, upgrade it with ‘exakat.phar upgrade -u’ and like us on github: https://github.com/exakat/exakat.