Exakat 0.12.3 review

Exakat 0.12.3 review : PHP 7.2 support, GraphQL experiments

Exakat 0.12.3 is out like a hot summer diner. For this week’s menu, we are served with support for the new PHP 7.2 syntax in grouped use, 2 analysis hunting down default values and typehint mismatches, and a recommendation to start using the Null Object Pattern. Exakat now also delivers data in GraphQL format, thanks to Marmelab. And, as usual, more work for the graph database.

PHP 7.2 new grouped use syntax

PHP 7 offers a grouped use syntax, where one may provide a suffix for several use expressions.

<php
use a\b\c\{ d, e, f};
// equivalent to 
use a\b\c\d, a\b\c\e, a\b\c\f;
?>

PHP 7.2 introduces the possibility to add a last comma, without specifying a final namespace. This is comparable to the last comma in an array definition.

<?php
use a\b\c\{ d, e, f, };
$a = array(1,2,3,4,);
?>

The main advantage of this new syntax is when committing the code to VCS. Version control likes to produce diffs, and it is inconvenient when the last element of a list is actually different.

<?php
use a\b\c\{ d, 
	      e, 
                  f, 
// new use : g,
};
?>

Adding a new ‘g’ to the grouped use above now means adding only one line (g,) instead of fixing the previous line and adding the new (, g). This helps keep diffs smaller, and easier to read.

Default values and typehint mismatch

Exakat now reports methods and typehint mismatch. For example :

<?php
function foo(A $a, B $b) {
	bar($a, $b);
}
function bar(AA $a, $b) { }
?>

Here, $a is an instance of A class in foo(), but is an instance of AA in function bar(). Although it is possible to has AA a parent class of A, the discrepancy leads to a bug. So, anytime a method, function or closure is calling another method with mismatched types, they are now reported. Note that non-defaulted arguments, calling or called, are omitted in this analysis.
The same applies to default values, though the report is less compelling than the previous one.

<?php
function foo($a = null, $b) {
	bar($a, $b);
}
function bar($a = array(), $b) { }
?>

This time, foo() may act as a parameterizing function for bar, and change the value on purpose. Although, most of the time, they have to be aligned to be actually useful.

Null Object Pattern

The null object pattern recommends the creation of an object that behave like null, without the fatal errors related to null. For example, in this code :

<?php
class x {
	public $foo = null;

	function foo($string) {
		if ($this-&gt;foo !== null) {
			$this-&gt;foo-&gt;display($string);
		}
	}
}
?>

The default value of $this->foo is null. That leads to checking the content of $this-> foo each time it has to be used, so as to know if echo or display has to be called.
A null object should help with the above code, by providing a foo value that is always existing.

<?php
class x {
	public $foo = null;
	function __construct() {
		$this-&gt;foo = new nullDisplay();
	}
	function foo($string) {
		$this-&gt;foo-&gt;display($string);
	}
}
interface myDisplay {
	function display($string) ;
}
class nullDisplay implements myDisplay{
	function display($string) {} // empty on purpose
	// other methods if needed.
}
?>

Now, there is no more need to check if $this->foo is an object or not (besides the fact that being public, it may be erroneously set). NullDisplay handles the cases where no display method is provided, and behaves like a normal display class, though doing nothing.
The null object patterns tends to reduce the amount of check on properties, by providing a consistent value. The analysis focuses on finding properties that have a dual nature, like scalar or object, and report them as a good candidate for a null object pattern.

GraphQL for exakat

GraphQL is the latest hype when it comes to API. It appears to be a good way to publish exakat’s results. Currently, we provide a database of reported issues, that may be navigated thanks to the reports : HTML, json, xml, text, etc.
When it comes to specific queries, the current solution is to write then in SQL, and build a new report. None of this is documented yet, so if you are interested, you still have to wait or ping the team.

GraphQL is a query language and a server that serves the data. Last week, Francois Zaninotto released a ‘ full fake GraphQL API ‘ : a GraphQL server made to learn the new language. It works with a JSON file, which Exakat produces. Once started, we may query the server with a GraphQL client, like graphiql, or in command line.

php exakat.phar report -p -format Marmelab -file marmelab
cp projects/myproject/marmelab.json path/to/marmelab
json-graphql-server db.json

From there, you may query localhost:3000, or use graphiql to build a query.

At the moment, the issues are provided in the marmelab.json file, along with the analyzer docs. We’ll follow the next versions of the server to keep up with the new features.
In the mean time, feel free to experiment and keep us updated. Marmelab graphql server was fast to set up and run, perfect for testing. Adding graphQL support to exakat should also open new opportunities, to extract the informations you need from the audit report. Join us on Slack or via twitter if you need more, we’ll gladly hear from you!

Graph database : Tinkergraph and Janusgraph

Graph database ground work is going on nicely. So far, Tinkergraph and Janus have been added, and they provide a significative boost in performance and ease of installation. We are now ramping up the architecture, so as to break the half-million tokens in the graph, so stay tuned for the next versions!

Happy PHP code reviews

Exakat 0.12.3 offers better PHP 7.2 support and GraphQL experiments. We also received suggestions from skoop and Marcus Bointon (PHPMailer) : many thanks to them! Summer time is a great moment to take a better look at your code : why not an exakat audit ? Install it, run it and tell us about it!
All the 310+ analyzers are presented in the docs, including the PHP 7.0 ‘Random without try‘, which reports usage of random number generation functions without a try / catch block. Download Exakat on exakat.io, upgrade it with ‘exakat.phar upgrade -u’ and like us on github: https://github.com/exakat/exakat.