Exakat 1.7.6 Review

Exakat 1.7.6 provides a new report that configure php-cs-fixer and automates fixes in the code. This means that after a good audit, the code may be systematically updated and cleaned of all issues for the next audit. We also introduced a detector for PHP overridden functions, array_merge() used raw with ellipsis and a new favorite : the caught exception variable. Code can only be understood backwards; but Exakat 1.7.6 review must be read forwards. 

Fast Issues Removal With php-cs-fixer

The PHP Coding Standards Fixer (PHP CS Fixer) tool fixes your code to follow standards. Its main goal is to make automated updates in PHP code to follow coding standards. For example, making sure that arrays are declared with array or with [], but not with both. php-cs-fixer comes with defined coding standards, like PSR-1PSR-2

php-cs-fixer also includes micro-optimisations : for example, replacing is_null($var) with $var === null is faster, because operators are faster than a function call. It is also a micro-optimisation, since the performance gain is a few micro-seconds : unless this is in a loop, the effect will be small.

Exakat is able to produce a php-cs-fixer configuration file, based on the last audit, that will fix issues automatically. Since a number of php-cs-fixer are shared with Exakat, issues found by Exakat may be fixed automatically by php-cs-fixer. 

Here are the operations for fixing your code en masse : 

  • Run an exakat audit. Make sure that the ruleset Phpcsfixer is included in the configuration, either in config/exakat.ini file, or in command line, with --format Phpcsfixer option with the project command. 
  • Get the configuration file : php exakat.phar report -p <project> -format Phpcsfixer. The produced file is projects/<project>/php_cs.php.
  • The resulting file may be like this : 
<?php

$finder = PhpCsFixer\Finder::create()
    ->in('.')     // Change this to your code's path
    ->name('*.php');

return PhpCsFixer\Config::create()
    ->setRules(        
                array (
                  'no_short_bool_cast' => true,
                  'is_null' => true,
                  'function_to_constant' => true,
                  'elseif' => true,
                  'dir_constant' => true,
                  'combine_nested_dirname' => true,
                  'combine_consecutive_issets' => true,
                  'combine_consecutive_unsets' => true,
                  'logical_operators' => true,
                  'no_unset_on_property' => true,
                )
    )
    ->setFinder($finder);
  • Save that file in your code, under the name .php_cs
  • Run php vendor/bin/php-cs-fixer fix --dry-run to check how much of the code will be updated
  • Run php vendor/bin/php-cs-fixer fix to actually fix the code
  • Commit to your VCS
  • Run a new Exakat audit : those issues are now gone!

A word of caution : as with any tool that update automatically code, always review the fixes from php-cs-fixer before committing them. Also, run your tests to ensure that the code is still working as expected.

PHP overridden functions

Exakat reports PHP overridden functions. Overridden functions are native PHP function, that have their own custom definition. This happens in namespaces. For example : 

<?php

namespace {
    // displays a path
    echo dirname('/path/to/file');
}

namespace Mine {
    function dirname() {
        return __METHOD__;
    }

    // displays a method name
    echo dirname();
}

?>

The first call to dirname is a PHP native dirname. The second call to dirname is nested in a custom namespace, and leads to the local dirname function, with a very different behavior. 

As long as no definition for dirname is added to the Mine namespace, PHP fallback to global space and use the native version. When a namespaced definition for a function is available, then the syntax doesn’t change but the native function is wired to another definition. This may lead to confusion. 

PHP overridden functions are reported in the Appinfo section of the Ambassador report, so as to warn auditors that these features is being used in the code. It is not reported as an issue. 

Array_merge() And Ellipsis

Array_merge() is a powerful function that merges an arbitrary list of arrays into one. 

<?php
  $arrays = [[1,2], [3,4,5], [6]];
  $final = array_merge(...$arrays);
  // $final contains [1,2,3,4,5,6];
?>

$arrays contains a list of arrays. They are expanded as individual arguments when provided to array_merge(), thanks to the ellipsis operator : ...

Using ... and arraymerge() is a important performance gain when merging a lot of arrays. Each call to arraymerge() makes it allocate memory for a new array, containing all the arguments. As such, it is important to make only one call, and same a lot of allocations. Read more in the No array_merge() in loops rule. 

One of the limitations of ... is that it returns null when the array is empty. 

<?php
  $arrays = [];
  $final = array_merge(...$arrays);
  //PHP Warning:  array_merge() expects at least 1 parameter, 0 given in Standard input code on line 3
?>

Empty() array leads to a warning that will pollute the logs. On the other hand, array_merge() is able to handle a unique empty array : it simply returns that empty array. 

The solution is to check the content of the array of arrays before using it. This may be done with a if/then condition, or by using the null coalesce ?? operator, in combination with ...

<?php
  $arrays = [];
  $final = array_merge(...$arrays ?? [[]] ); // nested arrays
?>

New favorite : The caught exception

Exceptions are caught with the catch clause. Taken from the manual, everyone uses $e as the name for the caught exception. While there is no convention for naming that variable, it is interesting to inventory the various names that are used. 

Among names, the caught variable may be $e$oExcept$oE$httpException$ae$error$a$exception$except$ex$e2$zhce$exc$nva$re$t, ….

The Weekly Audits: 2019, Week #17

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 : 2019, week 2019-17

Happy PHP Code Reviews 

All the 352 analyzers are presented in the docs, including the grand: If With Same Conditions : Successive If / then structures that have the same condition may be either merged or have one of the condition changed.

It is a common bug, found in 44% of source codes.

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.