Skip to main content

Using array shape as custom type in PHPStan

This blog post might be outdated!
This blog post was published more than one year ago and might be outdated!
· 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.