Skip to main content

Using array shape as custom type in PHPStan

· 2 min read
Stephan Hochdörfer
Head of IT Business Operations

My friend Beau Simensen recently asked on Mastodon if it is possible to pass an array shape as a type to a function?

Good question. And the answer is yes. Here's how it works.

Assuming, you want PHPStan to check this code and make sure that the $array parameter passed to the function has both required array keys min and max set:

function test(array $array): bool
{
return $array['max'] < $array['min'];
}

We can define a global type alias in PHPStan in the configuration file like this:

parameters:
typeAliases:
MyArrayType: 'array{min: int, max: int}'

Now we can add the MyArrayType type alias to the function to help PHPStan better understand the situation:

/** @param MyArrayType $array */
function test(array $array): bool
{
return $array['max'] < $array['min'];
}

Thanks to the custom type alias, PHPStan is able to run the following checks:

  1. Does the function internally only use the keys exposed by the MyArrayType type? In case we have a typo in the code and try to access the mat key instead of the max key, PHPStan will detect this issue:
Offset 'mat' does not exist on array{min: int, max: int}.
🪪 offsetAccess.notFound
  1. Does the caller provide the defined array keys of the MyArrayType type when calling the function? In case we pass a key that is not configured by the custom type definition, PHPStan will tell us:
Parameter #1 $array of function test expects array{min: int, max: int}, array{mat: 5} given.
🪪 argument.type
💡 Array does not have offset 'min'.

Type aliases greatly assist PHPStan in comprehending "non-class" structures within your code, enabling it to perform various validations.