Skip to content

PHPStan Tips

Oscar Merida edited this page Jan 15, 2025 · 5 revisions

No return type specified for function/method

Check the body of the function for return statements that return a variable or value.

  • If it's a scalar value, add a return type hint to the signature: function foo(string $in): string
  • Multiple types can be combined: function foo(string $in): bool|string
  • If it returns a class, check if the class returns an interface. If it does, set the Interface as the return type hint, otherwise use the classname. function foo(string $in): NodeInterface
  • If it returns an array, set the return type to array. You'll have to describe what kind of an array is returned via a docblock comment.
  • If it doesn't return any values, like most preprocess hooks, set the return type to void function foo(string $in): void

Variables always exist

If PHPSTan complains that "Variable $x on left side of ?? always exists and is not nullable", it's saying that based on the types $x will always have a nopn- value so the null coallesce operator will not do anything. Usually, it's an expressoin line like this:

do_something($x ?? NULL),

It can be replaced with:

do_something($x);

Describring arrays via docblocks

When you use the array type hint for an argument or return type, PHPStan will ask you to describe it via docblock

Function foo() has parameter $bar with no value type specified in iterable type array.

If it is an array of scalar values (ints, strings, etc), add square brackets after the type.

/**
 * @param int[] $x
 * @return string[]
 */
function foo(array $x): array

Likewise, if its an array holding objects of a specific class:

/**
 * @param NodeInterface[] $x
 */
function foo(array $x): bool

The syntax below can be used arrays with string indexes. If it's a simple list holding the same scalar types, you can indicate that in the docblock with angle brackets.

$opt = [
   'title' => 'Foo',
   'author' => 'Jane Doe',
];


/**
 * @param array<string, string> $options
 */
function foo(array $options): void {

}

If the keys can be anything and values can be arbitrary types , including objects, use mixed. Arrays used by hooks and preprocess functions are like this.

// caller can set whatever key and values they want
$opt = [
   'title' => 'Foo',
   'author' => $authorObject,
   'pubDate' => new \DateTime('March 3, 2012');

];


/**
 * @param array<string, mixed> $options
 */
function foo(array $options): void {

}

If you know the keys are limited to set of values, you should describe the array shape as specifically as possible.

// array must have these 3 keys
$opt = [
   'title' => 'Foo',
   'author' => $authorObject,
   'pubDate' => new \DateTime('March 3, 2012');
];


/**
 * @param array{title: string, author: app\Author, pubDate: \Datetime> $options
 */
function foo(array $options): void {

}