Exakat 1.5.6 Review
This week, on radio Exakat 1.5.6 : we added analysis to report the too verbose isset($a) && isset($a[1])
, support for the SDL extension, and a check on useless trait’s method aliases. We also fixed a nest of nasty syntax, thanks to PHP own unit tests. Quick, Robin, to the Exakat 1.5.6 review.
Deep Isset() On Arrays
isset is a native PHP language construct (not a function), which checks the existence of a variable. When applying isset()
to a multidimensional array, we often see that piece of code :
<?php if (isset($a) && isset($a[1]) && isset($a[1]['source'])) { doSomethingWith($a[1]['source']); } ?>
It looks like a very thorough verification of the existence of the array $a
, and the index 1
in the array $a
, and the index source
in the array $a[1]
.
What is omitted here is that isset() already does that job, and a simple call is needed for the same result :
<?php if (isset($a[1]['source'])) { doSomethingWith($a[1]['source']); } ?>
isset() does check each index on after the other, and will only return true if every index and the initial variable are set. Otherwise, it will fail, and silently.
The first analysis shows that a lot of code will benefit from this new suggestion.
Support for the ext/sdl extension
Following a tweet about phpOkoban from Benoit Viguier, we discovered a nice PHP extension called SDL, written by Santiago Lizardo and Remi Collet.
SDL : Simple DirectMedia Layer is a cross-platform development library designed to provide low-level access to audio, keyboard, mouse, joystick, and graphics hardware via OpenGL and Direct3D.
ext/SDL has now joined the 165 recognized PHP extensions by Exakat.
Useless Trait Alias
When loading traits inside a class, it is forbidden to declare an alias with the same name as the original method. And, of course, it is useless, since the method is already bearing that name.
<?php trait t { function m() {} } class x { use t { m as m; } } ?>
The problem is related to the moment where this tragic error is discovered. In fact, PHP does lint this code above, without a problem. This is fine.
Then, at execution time, the class is built, and we get a PHP Fatal Error
: Trait method m has not been applied, because there are collisions with other trait methods on x
.
Read the message, and learn that you can’t alias a method m
, because there is already a method called m
in that class.
This behavior is very different from the other use : the namespace use. This one accepts to declare the alias with the same name :
<?php use t as t; trait t { function m() {} } class x { use t { m as m; } } ?>
So, be aware of the distinction : use
expression behave very differently. Using namespaces: Aliasing/Importing and Traits.
Lots of Weird Syntax
We ran into a nest of strange syntax, last week. They really surprised us, and they are now under control. Now, it is funny to recall them.
One of them is the relaxed keyword syntax, which allows us to use a lot of PHP keywords as method names. foreach
, as
and then
are valid method names (not functions, but methods).
When those methods end up in a trait, and you need an alias, you may write this :
<?php use t as t; trait t { function foreach() {} } class x { use t { as as foreach; } } ?>
Yes, as as foreach
means that the as
method should also be called foreach
in the class x. Funny, right ?
Another strange syntax we ran into was the fact that yield
actually returns something, and it may be used in an array.
<?php function foo() { return [yield]; } ?>
In PHP 7.2, foo() will return once the yields are all executed. This will fill the array with null
. This is weird, and probably useless, but it’s fun to write (and weird, but we already mentioned it…)
Finally, the last curious thing is this one :
<?php $a[2 => 'a', -2 => 'b']; echo "$a[-2]"; // This one is a syntax error //echo "$a[+2]"; ?>
Since PHP 7.1, we have the ability to use negative numbers as index inside a string. Outside a string, this goes without saying, but inside ? The hidden problem is that -2, or ‘minus two’, is really two different token : minus, (the same one that we use for additions), and two (the one we use for… well.. two).
Inside a string, the index has to be simple, and they can’t have two tokens, so -2 was forbidden until PHP 7.1. Now, since PHP 7.1, -2 is allowed, but ONLY with minus. A special pattern was added to the PHP parser, and minus-integer is recognized. But nothing was added for plus-integer, so +3 is invalid.
Do we need that? Probably not. We lived very well without it, so it is fine. But it’s fun… That may end up in a quizz….
The Weekly Audits : 2018, Week #49
Exakat includes a ‘weekly’ report : this report is built with a selection of five analyses. This means a short audit report, with few issues to review. This is not a lot to read them, and review them in your code. Everyone in the PHP community can focus on one of the classic coding problems and fix it. Talk about the weekly audit around you : you’ll find programmers facing the same challenges.
To obtain the ‘weekly’ audit, run an audit, and request the ‘Weekly’ report.
# Init the project (skip when it is already done)
php exakat.phar init -p <yourproject> -R https://github.com/Seldaek/monolog.git -git
# Run the project (skip when it is already done)
php exakat.phar project -p <yourproject>
# Export the weekly project (every monday)
php exakat.phar report -p <yourproject> -format Weekly
# Open projects/<yourproject>/weekly/index.html in your browser
Every week, you can find here 5 new analysis to review in your code. In fact, when your code is clean, you can also take a quick look at the upcoming
Weekly recommendations for PHP code review : 2018, week 2018-49
- Use Instanceof : The
instanceof
operator is a more precise alternative tois_object()
. - Wrong Number Of Arguments In Methods : Those methods are called with a wrong number of arguments : too many or too few.
- Abstract Or Implements : A class must implements all abstract methods of it parent, or be abstract too.
- Catch Overwrite Variable : The try/catch structure uses some variables that are also in use in this scope.
- Undefined static:: Or self:: : self and static refer to the current class, or one of its parent.
Every week, you can find here 5 new analysis to review in your code. In fact, when your code is clean, you can also take a quick look at the upcoming week with the ‘Go further’ section.
Happy PHP Code Reviews
All the 352 analyzers are presented in the docs, including the inevitable Written Only Variables: : the magical syndrome of variables that are written, but never read. It is a ubiquitous bug : 74% applications mishandle variables.
You can check all of the Exakat reports at the gallery: exakat gallery.
Download Exakat on exakat.io, install it with Docker, upgrade it with ‘exakat.phar upgrade -u’ and like us on github.