yii2-extensions / phpstan
PHPStan extension for Yii2
Requires
- php: >=8.3
- nikic/php-parser: ^4.1|^5.4
- phpstan/phpstan: ^2.3
- yiisoft/yii2: ~2.0.55 || ^22.0@dev
Requires (Dev)
Suggests
None
Provides
None
Conflicts
None
Replaces
None
README
PHPStan
Enhanced static analysis for Yii2 applications with PHPStan
Precise type inference, dynamic method resolution, and comprehensive property reflection
Features
Installation
composer require --dev yii2-extensions/phpstan:^0.5
Quick start
Create config/phpstan.php with an analysis-only description of your application:
<?php declare(strict_types=1); return [ 'params' => ['adminEmail' => 'admin@example.com'], 'components' => [ 'db' => ['class' => yii\db\Connection::class], ], ];
Create phpstan.neon in the project root, choosing paths that exist in your application:
includes: - vendor/yii2-extensions/phpstan/extension.neon parameters: level: 5 paths: - models yii2: config_path: config/phpstan.php
Run PHPStan:
vendor/bin/phpstan analyse
Type inference examples
The snippets below assume an app\models\Article model with id and title property tags and a published() query
scope. The usage guide describes the analysis configuration for the components, params and behaviors
shown here.
Active Record
Yii supplies generic types for findOne(), findAll(), relations and the standard query methods. This extension adds
row shapes from model @property tags and precise getAttribute() types:
use app\models\Article; $article = Article::findOne(1); // Article|null $articles = Article::findAll(['title' => 'Yii']); // array<Article> $query = Article::find()->where(['id' => 1]); // ArticleQuery&ActiveQuery<Article> $published = Article::find()->published()->one(); // Article|null $rows = Article::find()->asArray()->all(); // array<array{id: int, title: string}> if ($article !== null) { $title = $article->getAttribute('title'); // string }
A custom query without generic PHPDoc, such as one generated by Gii, is bound to the model at the find() call site.
Use static or $this scope return types to preserve that binding. Row shapes include inherited property tags;
relation and read-only keys are optional and need guards such as ??. See
query limitations when a query is reached through a typed parameter or a
widened relation getter.
Application components
Yii::$app uses phpstan.application_type, which defaults to yii\web\Application. Component classes come from the
analysis configuration:
$view = Yii::$app->exampleView; // yii\web\View $typed = Yii::$app->get('typedView'); // yii\web\View $untyped = Yii::$app->get('untypedView'); // object $request = Yii::$app->request; // yii\web\Request
Class names, class-key arrays, object instances and factories with a single class return type can provide precise types.
An untyped factory yields object; adding an accurate return type makes the result specific. Core components configured
without a class keep the application's annotated property type.
The built-in user: identityClass mapping also supplies the configured identity class to yii\web\User's generic
parameter. Its identity property remains nullable. See generic components
and the separate console application configuration.
Application params
Params values become an array shape, including nested arrays and keys containing dots or other punctuation:
$email = Yii::$app->params['adminEmail']; // string $maxItems = Yii::$app->params['maxItems']; // int $enabled = Yii::$app->params['nested']['enabled']; // bool
Scalars are widened to their types rather than retained as literal values. The same shape applies to inherited module
params, including $this->module->params in a controller. With no configured params, the type stays array.
Behaviors
The analysis-only behaviors map exposes members from attached behavior classes. In the example, TaggedComponent is
mapped to TagBehavior; the application must also attach that behavior at runtime:
use app\behaviors\TagBehavior; use app\components\TaggedComponent; $component = new TaggedComponent(); $component->attachBehavior('tag', new TagBehavior()); $label = $component->label; // string $summary = $component->summarize(); // string
Properties and methods are resolved from the behavior's native members and PHPDoc. See behavior configuration.
Dependency injection
Container service definitions and aliases are resolved by their IDs:
$view = Yii::$container->get('view.alias'); // yii\web\View $shared = Yii::$container->get('sharedView'); // yii\web\View
The example config maps view.alias to view.real and gives sharedView a typed factory. An unresolved definition
keeps the result as object. Container factories, invocable objects and aliases have distinct rules; see
definition forms.
Header collection
$headers = new yii\web\HeaderCollection(); $host = $headers->get('Host'); // string|null $ids = $headers->get('X-Request-ID', [], false); // array<string> $requestId = $headers->get('X-Request-ID', 'default'); // string
A non-null default removes null from the return type. The $first argument selects a single value or an array.
Logger messages
Logger and target message buffers have tuple types without local stubs or PHPDoc overrides:
foreach ((new yii\log\Logger())->messages as $message) { $level = $message[1]; // int $category = $message[2]; // string $timestamp = $message[3]; // float $memory = $message[5] ?? null; // int|null } $empty = yii\log\Target::filterMessages([]); // array{}
Payload types follow the installed Yii version. Filtering preserves the input key and tuple types while allowing an empty result. See the logger examples.
Service locator
A service locator resolves configured component IDs, while container-only IDs belong to the container:
$view = Yii::$app->get('exampleView'); // yii\web\View $optional = Yii::$app->get('exampleView', false); // yii\web\View|null $unknown = Yii::$app->get('view.alias'); // object; not a configured component ID
Passing false or a non-constant boolean as $throwException makes a resolved component nullable. An object fallback
does not guarantee a successful runtime lookup: unknown component IDs can throw. Use
Yii::$container->get('view.alias') for the configured container alias.
Documentation
Practical guides and complete examples for Yii type inference and application analysis.
- ๐ Installation Guide
- โ๏ธ Configuration Guide
- ๐ก Usage Examples
- ๐ Upgrade Guide and Migration Guide
- ๐งช Testing Guide
The guides and the API reference generated from
the PHPDoc in src/ are published at https://yii2-framework.github.io/docs/extensions/phpstan/.
AI assistance
AI agents: read the documentation index and fetch the Markdown version
of a page by appending index.md to its URL. The
AI agents guide covers skill installation, client setup and
verification.
- ๐ค
yii2-phpstan-analysisskill: Static analysis. - ๐งญ
yii2-frameworkskill: Yii 22.0 application conventions.
The hosted documentation covers Yii 22.0. If it does not match the installed revision or is unavailable, use the repository guides, the skill source, the source PHPDoc and the changelog.