In PHP, the array
type is commonly used to represent three different data structures:
List:
<?php
$a = [1, 2, 3, 4, 5];
<?php
$a = [0 => 'hello', 5 => 'goodbye'];
$b = ['a' => 'AA', 'b' => 'BB', 'c' => 'CC']
Makeshift Structs:
<?php
$a = ['name' => 'Psalm', 'type' => 'tool'];
PHP treats all these arrays the same, essentially (though there are some optimisations under the hood for the first case).
Psalm has a few different ways to represent arrays in its type system:
Psalm uses a syntax borrowed from Java that allows you denote the types of both keys and values:
/** @return array<TKey, TValue> */
You can also specify that an array is non-empty with the special type non-empty-array<TKey, TValue>
.
PHPDoc allows you to specify the type of values a generic array holds with the annotation:
/** @return ValueType[] */
In Psalm this annotation is equivalent to @psalm-return array<array-key, ValueType>
.
Generic arrays encompass both associative arrays and lists.
(Psalm 3.6+)
Psalm supports a list
type that represents continuous, integer-indexed arrays like ["red", "yellow", "blue"]
.
A frequent way to create a list is with the $arr[] =
notation.
These arrays will return true to array_is_list($arr)
(PHP 8.1+) and represent a large percentage of all array usage in PHP applications.
A list
type is of the form list<SomeType>
, where SomeType
is any permitted union type supported by Psalm.
list
is a subtype ofarray<int, mixed>
list<Foo>
is a subtype ofarray<int, Foo>
.
List types show their value in a few ways:
<?php
/**
* @param array<int, string> $arr
*/
function takesArray(array $arr) : void {
if ($arr) {
// this index may not be set
echo $arr[0];
}
}
/**
* @psalm-param list<string> $arr
*/
function takesList(array $arr) : void {
if ($arr) {
// list indexes always start from zero,
// so a non-empty list will have an element here
echo $arr[0];
}
}
takesArray(["hello"]); // this is fine
takesArray([1 => "hello"]); // would trigger bug, without warning
takesList(["hello"]); // this is fine
takesList([1 => "hello"]); // triggers warning in Psalm
Psalm supports a special format for arrays where the key offsets are known: object-like arrays, also known as array shapes.
Given an array
<?php
["hello", "world", "foo" => new stdClass, 28 => false];
Psalm will type it internally as:
array{0: string, 1: string, foo: stdClass, 28: false}
You can specify types in that format yourself, e.g.
/** @return array{foo: string, bar: int} */
Optional keys can be denoted by a trailing ?
, e.g.:
/** @return array{optional?: string, bar: int} */
An array holding a callable, like PHP's native call_user_func()
and friends supports it:
<?php
$callable = ['myClass', 'aMethod'];
$callable = [$object, 'aMethod'];
An array which is not allowed to be empty.