Introduction to PHP type-hints for Drupal 8 development

When you are calling a function or method that has an argument(s), you don’t always know what type (array, object, string etc) of argument to pass to the function. And if you end up passing in the wrong type, you’ll get a less than helpful error.

To fix this, you can using type-hints to improve the clarity of your code and improve errors. Type hinting allows you to specify data types you expect for an argument for a function declaration. You can specify data types such as arrays, objects and interfaces. Type-hinting is optional, but it does makes it easier to debug your code and allows your IDE to provide autocompletion amongst other benefits.

Consider the following simple example:

<?php

$ingredients  = array('banana', 'strawberry');

function shake ($ingredients) {
  foreach($ingredients as $ingredient) {
    print $ingredient;
  }
}

shake($ingredients);

This will print banana and strawberry to the screen.

But it isn’t immediately clear that the $ingredients argument in the shake function needs to be an array. So what happens if you pass in a string instead?

$ingredients = 'coconut';

function shake ($ingredients) {
  foreach($ingredients as $ingredient) {
    print $ingredient;
  }
}

shake($ingredients);

You will get the following error:

Warning: Invalid argument supplied for foreach()

The error is referencing the foreach because you have tried to pass it a string when it was expecting an array.

To use a type-hint with this example, add the date type to the function argument. In this case, the data type is array.

function shake (array $ingredients) {
  foreach($ingredients as $ingredient) {
    print $ingredient;
  }
}

Then if you pass in the string, you will get a more meaningful error:

$ingredients = 'coconut';

function shake (array $ingredients) {
  foreach($ingredients as $ingredient) {
    print $ingredient;
  }
}

shake($ingredients);

The error is now:

Catchable fatal error: Argument 1 passed to shake() must be of the type array, string given, called in /Users/blairwadman/Sites/tutorials/typehinting/index.php on line 13 and defined in /Users/blairwadman/Sites/tutorials/typehinting/index.php on line 7

This is very meaningful and tells you exactly what the problem is and the line it is on.

Object type hinting

You can also specify a class or interface as the type-hint.

Consider the following Drupal implementation of hook_form_alter():

<?php
/**
 * Implements hook_user_login($account).
 *
 * @param $account
 */
function welcome_user_login($account) {
  $name = $account->getDisplayName();
  drupal_set_message(t('Hello @name, thank you for logging in and welcome!', ['@name' => $name]));
}

You now have the display name from $account. But you have to know that getDisplayName() is an available method.

Fortunately, there is an easier way if you use a type-hint and an IDE like PHPStorm.

If you include a base class or interface for the $account variable, your IDE will tell you the available methods and properties.

Add ‘AccountInterface’ type-hint to the welcome_user_login() function:

function welcome_user_login(\Drupal\Core\Session\AccountInterface $account) {

And now when you start to type $account-> , the IDE will offer you autocompletion.

Adding a use statement

You can also include a use statement in the .module file so that you can reference 'AccountInterface' rather than the full namespace hierarchy.

At the top of .module file, add the following use statement:

use Drupal\user\AccountInterface;

Change the function argument:

function welcome_user_login(AccountInterface $account) {

Putting this all together, welcome_user_login() is now:

<?php

use Drupal\user\UserInterface;

/**
 * Implements hook_user_login($account).
 *
 * @param $account
 */
function welcome_user_login(UserInterface $account) {
  $name = $account->getDisplayName();
  drupal_set_message(t('Hello @name, thank you for logging in and welcome!', ['@name' => $name]));
}

Wrapping up

Using type-hints in your code makes it clearer and less error prone, improves the errors you get back and also aids in autocompletion. Type-hints aren’t part of the Drupal code standards yet (so they are not required for core and contributed code) yet, but you find plenty of examples in core code.

Add new comment