Typehint Recommendations for AllTypehint Recommendations for All

The process of adding strong typing to a PHP code base is a long process. A standard application will require on average 11 000 arguments and return type to add, and that is not counting the properties (everyone is on PHP 7.4, right?)

The vast majority of typehints are already in the code. One may deduce them from reading the source, and checking for usage and prerequisites. And that is a work for static analysis tool.

Typehint suggestions

Here is an example of the results from the ‘typehint suggestion’ report of Exakat. Functions, closures, arrow functions and methods (traits and class) are presented in a table.

Standalone functions are sorted first, while methods are displayed after.

functions

Functions are presented first. They are referenced by their name. Parameters and return type are displayed in the third column. When a typehint is present in the code, it is displayed. Otherwise, Exakat displays one or several type suggestion.

closures

Closures are presented next. The format is the same as for functions, although the file and line are used to distinguish the closures. The names of the parameters may also help to distinguish them.

Arrow functions are displayed like closures.

Classes, interfaces and traits

All of them are presented with their class name, and their namespace below. Properties are presented first, or simply omitted when there is none.

Each method gets a green tick to mention that all parameters and the return type have been specified in the code : so far, so good.

Classes also get a tick, when all methods also have a tick, or when all properties have a tick. Also, when all properties and methods have the typehints.

Suggestions

The last column is the suggestion column. It contains possible types that Exakat could find. You’ll find the scalar types, and also iterable.

Nullable typehint, which is represented with ? in PHP 7.x, is represented with null in the report. The null notation will be the available in PHP 8.0 code, and it makes the report easier to read.

The PHP 8.0 type stringeable is not supported yet.

Class, Interface type is a generic suggestion to cover any object. It is possible to use the object scalar type in the code, although it won’t help much. Currently, no further detail is provided on which class or interface is possible. Although it is not always possible to detect it, details on possible classes will be available in a future release of Exakat.

It is also possible that no suggestion is provided. This might be a legit situation, like when a property acts as a cache for any kind of data; or because the method could not be found in the code; or if suggestions depends on typehints that are not yet coded (a.k.a, chained suggestions). And if we missed a case, drop us a note.

Inking the Typehints

With the suggestions at hand, it is simply a matter of choosing the right one to use. Several situations are possible and require different treatments.

One type is suggested. Check for yourself, and just use it. If the second type is null : then, use the nullable type with ?.

Multiple types are suggested. Then, you may have yourself the following questions : + Does the method actually handle multiple types? For example, with is_array() or instanceof ? It will probably need those multiple types. Stay in PHP 7.x and do not add any type; move to PHP 8.0 and use union types. + Does the method should use one of those types? Then use the type, and be ready to fix some types here and there. This is a situation where compelling a parameter to be int will suddenly raise red flags for any part of the code sending a string or a null. Exakat checks the actual usage of the method, and if string are used, it will suggest that type too.

Last piece of advice : don’t do too many of them at once. Add them by small batch, and see the impact on your code, and on the audit itself.

Running the audit on your code

Are you ready to get your own suggestions? Let’s go!

  • Install Exakat
  • Run the audit
  • Update your code

Install Exakat

Installing Exakat comes in various flavors, including Docker or commandline. We’ll do the commandline version.

You need PHP 7.4, or 7.3 to run Exakat. You need Java 8, unzip already installed on the target machine. That should be a low bar to pass.

Let’s do the curl installation quickly. Copy and paste the following script :

mkdir exakat cd exakat curl -o exakat.phar 'https://www.exakat.io/versions/index.php?file=latest' php exakat.phar install

# Optional health check php exakat.phar doctor

The install command download a copy of the tinkergraph database, and install it in the same folder as Exakat.

The doctor command will display the current installation.

Run the audit

Let’s run a quick audit on an open source project so we can both check the installation and get our first results.

First, we initialize the project itself, run the audit, and extract the typehint report :

cd exakat 
php exakat.phar init -p sculpin -R https://github.com/sculpin/sculpin.git  
php exakat.phar project -p sculpin -v 
php exakat.phar report -p sculpin -format Typesuggestion  

In the end, the report is in the file projects/sculpin/typehints.suggestion.html, that you can open with your favorite browser.

Update your code

If you have replaced sculpin with your own code, it is time to review the list of suggestions and adopt the one that makes sense in your code. Happy auditing!

Speed up the adoption of the strong types

Exakat takes the laborious work of checking your code from your arms, so you can spend more time on what matters the most : delivering great applications.

And this is just the beginning : with the audit above, you can generate several other reports, including security, performances, PHP 8 compatibility and others.