Exakat 2.1.9 reviewExakat 2.1.9 Review

Exakat 2.1.9 comes loaded with no fewer than 11 new analysis : half of them are for PHP 8.0, and the other half is for code quality. There is now a dedicated report for migration to PHP, with backward incompatibility, and also suggestions. Let’s dive in the Exakat 2.1.9 Review.

Migration to PHP 8.0

Exakat provides a special report : Migration PHP 8.0. It provides 11 analysis to prepare your code to PHP 8.0. The incompatibilities are listed in UPGRADING : they will be integerated in the main PHP documentation later in the year.

To get the report, you need exakat, then the following commands :

php exakat.phar init -p myproject -R <project_URL>
php exakat.phar project -p myproject
php exakat.phar report -p myproject --format Migration80 

At that point, the report is now in the projects/myproject/migration80/ folder. You may open the index.html in that folder to open it in your browsers.

You may also use the Text version :

php exakat.phar report -p myproject --format Text -T CompatibilityPHP80

This one will report the same information, directly in the standard output.

The current list of back-incompatibility is in the documentation. They cover :

  • $php_errormsg usage
  • (unset) usage
  • Concatenation and addition/bitshift
  • Mismatched parameter names
  • PHP 4 constructors

We are always listening for backward incompatibility that should be tracked and reported. Drop us a note @exakat on twitter.

PHP assumptions

We got inspired by From assumptions to assertions, by Rick Kuipers. It is a classic scourge of the PHP world : a weak check on data. The example below is a staple :

<?php

function foo($order) {
    if ($order !== null) {
      $order->getBill();
    }
}
?>

The $order argument is assumed to be either a valid order, or null. So, when it is not null, it must be an order, then methods may be called. This probably works well initially, when foo() is only called with actual orders, until the code drifts, and foo() gets called with other values.

The example above is related to objects. Yet, assumptions come in very different flavors.

<?php

function foo($user) {
    if (is_array($user)) {
      // if $x is an array, then it must hold a 'user' index.
      echo $x['user'];
    }
}

function foo(User $user) {
      // if $x is a user object, then it must hold a 'user' property.
      echo $x->name;
}
?>

The second example is already covered with Insufficient Property Typehint rule, while wrongly called methods is covered by Insufficient Typehint.

The rule here is to use a strong assertion in the code : for example, using instanceof instead of !== null. This will ensure that the rest of the code is valid.

It is often seen as a speed improvement to use those assumptions, yet with maturity, the code is more stable with an extra check.

Optimise explode() with its third argument

The PHP native function explode has a third argument, which limit the number of exploded chunks. For example :

<?php
$string = '1,2,3,4,5';
$array = explode(',', $string, 3);
?>

This will produce an array with 3 elements, instead of 5. PHP stops working on the string as soon as it has enough elements : this saves some useless work, since those extra elements might not be used. For example :

<?php
$string = '1,2,3,4,5';
list($a, $b) = explode(',', $string, 2); // No need beyond 2

echo explode(',', $string, 3)[1];       // No need beyond 3

?>

This is a micro-optimisation : yet, the more elements are exploded, the better is the speed improvement. It may also protect the code from extra work, so it’s a nice passive safety.

Happy PHP Code Reviews

All the 402 analyzers are presented in the manual, including the noble : Large try blocks): Avoid using too large a try block. Keep it small, and focused on the actual call that may raise the exception.

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.