A PHPDoc type is whatâs written in place of [Type]
in annotations like @var [Type]
or @param [Type] $foo
. Learn more about PHPDoc basics »
Would you like to use advanced PHPDoc types in 3rd party code you have in /vendor? You can! Check out Stub Files »
Basic types #int
, integer
string
array-key
bool
, boolean
true
false
null
float
double
number
scalar
array
iterable
callable
, pure-callable
resource
, closed-resource
, open-resource
void
object
mixed
type can be used if we donât want to define a more specific type. PHPStan doesnât check anything on the mixed
type - any property or method can be called on it and it can be passed to any type in a function/method call.
PHPStan has a concept of implicit and explicit mixed
. Missing typehint is implicit mixed
- no type was specified as a parameter type or a return type. Explicit mixed
is written in the PHPDoc. PHPStanâs rule level 6 isnât satisfied with implicit mixed
, but an explicit one is sufficient.
Rule level 9 is stricter about the mixed
type. The only allowed operation you can do with it is to pass it to another mixed
.
A fully-qualified name (FQN) like \Foo\Bar\Baz
, or a relative name like Baz
resolved based on the current namespace and use
statements can be used.
Trait names cannot be used in PHPDocs, as they donât work as native PHP typehints either.
Integer ranges #positive-int
negative-int
non-positive-int
non-negative-int
non-zero-int
int<0, 100>
int<min, 100>
int<50, max>
Type[]
array<Type>
array<int, Type>
non-empty-array<Type>
non-empty-array<int, Type>
list<Type>
non-empty-list<Type>
Lists are arrays with sequential integer keys starting at 0.
Key and value types of arrays and iterables #key-of<Type::ARRAY_CONST>
value-of<Type::ARRAY_CONST>
class Foo {
public const WHEELER = [
'car' => 4,
'bike' => 2,
];
}
function repair(string $type, int $wheels): void
{
}
Additionally value-of<BackedEnum>
is supported:
enum Suit: string
{
case Hearts = 'H';
case Spades = 'S';
}
function foo(array $count): void
{
}
Iterables #
iterable<Type>
Collection<Type>
Collection<int, Type>
Collection|Type[]
These notations specify the iterable key and value types in a foreach statement.
These iterable rules are applied only when the Collection
type isnât generic. When itâs generic, generics rules for class-level type variables are applied.
If PHPStan encounters Collection|Foo[]
, two possible paths are taken:
Collection
implements Traversable
so Collection|Foo[]
is interpreted as a Collection
object that iterates over Foo
. The array part isnât applied.Collection
does not implement Traversable
so Collection|Foo[]
is interpreted as a Collection
object or an array of Foo
objects.If Collection|Foo[]
means âCollection
or arrayâ in your case even if Collection
implements Traversable
, you need to disambiguate the type by using Collection|array<Foo>
instead.
Written as Type1|Type2
. Read more about union types here »
Written as Type1&Type2
. Read more about intersection types here »
Parentheses can be used to disambiguate types: (Type1&Type2)|Type3
To denote that a method returns the same type itâs called on, use @return static
or @return $this
.
This is useful if we want to tell that a method from a parent class will return an object of the child class when the parent class is extended (see example).
A narrower @return $this
instead of @return static
can also be used, and PHPStan will check if youâre really returning the same object instance and not just an object of the child class.
Generics », Generics By Examples »
Conditional return types #A simpler alternative to generics if you just want to infer the return type based on if-else logic.
function fillArray(int $size): array
{
...
}
It can be combined with generics as well in both the condition and the if-else types:
public function fetch(int|array $id)
{
...
}
Utility types for generics #
template-type
can be used to get @template
type from a passed object argument. Related discussion here.
new
can be used to create an object type from a class-string type.
class-string
type can be used wherever a valid class name string is expected. Generic variant class-string<T>
also works, or you can use class-string<Foo>
to only accept valid class names that are subtypes of Foo.
function foo(string $className): void { ... }
Both literal strings with valid class names ('stdClass'
) and class
constants (\stdClass::class
) are accepted as class-string
arguments.
If you have a general string
and want to pass it as a class-string
argument, you need to make sure the string contains a valid class name:
function bar(string $name): void
{
if (class_exists($name)) {
foo($name);
}
}
Other advanced string types #
callable-string
is a string that PHP considers a valid callable
.
numeric-string
is a string that would pass an is_numeric()
check.
non-empty-string
is any string except ''
. It does not mean âemptyâ in the weird sense used by empty()
.
non-falsy-string
(also known as truthy-string
) is any string that is true after casting to boolean.
Security-focused literal-string
is inspired by the is_literal()
RFC. In short, it means a string that is either written by a developer or composed only of developer-written strings.
lowercase-string
accepts strings where strtolower($string) === $string
is true.
Type aliases (also known as typedef
) are a popular feature in other languages like TypeScript or C++. Defining type aliases will allow you to reference complex types in your PHPDocs by their alias.
You can define global type aliases in the configuration file:
parameters:
typeAliases:
Name: 'string'
NameResolver: 'callable(): string'
NameOrResolver: 'Name|NameResolver'
Then you can use these aliases in your codebase:
function foo($arg)
{
}
Local type aliases #
You can also define and use local aliases in PHPDocs using the @phpstan-type
annotation. These are scoped to the class that defines them:
class User
{
private $address;
}
To use a local type alias elsewhere, you can import it using the @phpstan-import-type
annotation in another classâ PHPDocs:
class Order
{
private $deliveryAddress;
}
You can optionally change the name of the imported alias:
class Order
{
private $deliveryAddress;
}
Array shapes #
This feature enables usage of strong types in codebases where arrays of various specific shapes are passed around functions and methods. PHPStan checks that the values in specified keys have the correct types:
array{'foo': int, "bar": string}
array{'foo': int, "bar"?: string}
(key bar
is optional in the array)array{int, int}
(keys are 0
and 1
, also known as a tuple)array{0: int, 1?: int}
(key 1
is optional in the array)array{foo: int, bar: string}
(quotes around array keys for simple strings arenât necessary)This is different from general arrays that mandate that all the keys and values must be of a specific homogeneous type. Array shapes allow each key and value to be different.
Object shapes #This feature is inspired by array shapes but represents objects with public properties with specified types:
object{'foo': int, "bar": string}
object{'foo': int, "bar"?: string}
(property bar
is optional in the object)object{foo: int, bar?: string}
(quotes around property names arenât necessary)Object shape properties are read-only. You can intersect the object shape with another class to make them writable:
object{foo: int, bar?: string}&\stdClass
PHPStan allows specifying scalar values as types in PHPDocs:
234
(integers)1.0
(floats)'foo'|'bar'
(strings; types can be combined with others)Constant enumerations are also supported:
Foo::SOME_CONSTANT
Foo::SOME_CONSTANT|Bar::OTHER_CONSTANT
self::SOME_*
(all constants on self
that start with SOME_
)Foo::*
(all constants on Foo
)Constants are supported as long as they donât contain lowercase letters and a class with the same name doesnât exist:
SOME_CONSTANT
SOME_CONSTANT|OTHER_CONSTANT
The callable
typehint has been in PHP for a long time. But it doesnât allow enforcing specific callback signatures. However, PHPStan allows to enforce specific signatures in PHPDocs:
callable(int, int): string
(accepts two integers, returns a string)callable(int, int=): string
(second parameter is optional)callable(int $foo, string $bar): void
(accepts an integer and a string, doesnât return anything; parameter names are optional and insignificant)callable(string &$bar): mixed
(accepts a string parameter passed by reference, returns mixed
)callable(float ...$floats): (int|null)
(accepts multiple variadic float arguments, returns integer or null)callable(float...): (int|null)
(accepts multiple variadic float arguments, returns integer or null)\Closure(int, int): string
(narrower Closure
type can also be used instead of callable
)pure-callable(int, int): string
(callable that doesnât have any side effects when called)pure-Closure(int, int): string
(Closure that doesnât have any side effects when called)Parameter types and return type are required. Use mixed
if you donât want to use a more specific type.
Aside from describing callable signatures PHPStan also supports declaring whether the callable is executed immediately or saved for later when passed into a function or a method.
PHPStan also supports changing the meaning of $this
inside a closure with @param-closure-this
PHPDoc tag.
All of these names are equivalent:
never
never-return
never-returns
no-return
Marking a function or a method as @return never
tells PHPStan the function always throws an exception, or contains a way to end the script execution, like die()
or exit()
. This is useful when solving undefined variables.
Some functions accept a bitmask composed by |
-ing different integer values. 0
is always part of the possible values. Some examples:
int-mask<1, 2, 4>
(accepts values that can be composed using |
from the given integers, and 0)int-mask-of<1|2|4>
(the same as above, but written as a union)int-mask-of<Foo::INT_*>
(accepts values from all constants on Foo
that start with INT_
)You can access a value type of a specific array key:
class HelloWorld
{
public function getBar()
{
}
}
This feature shines when combined with generics. It allows to represent key-value pairs backed by an array:
trait AttributeTrait
{
private array $attributes;
public function setAttribute(string $key, $val): void
{
}
public function getAttribute(string $key)
{
return $this->attributes[$key] ?? null;
}
}
class Foo {
use AttributeTrait;
}
When we try to use class Foo
in practice, PHPStan reports expected type errors:
$f = new Foo;
$f->setAttribute('bar', 5);
$f->setAttribute('foo', 3);
$f->getAttribute('unknown');
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4