https://github.com/yii2-extensions/phpstan
PHPStan plugin.
https://github.com/yii2-extensions/phpstan
phpstan yii2 yii2-extensions
Last synced: 2 months ago
JSON representation
PHPStan plugin.
- Host: GitHub
- URL: https://github.com/yii2-extensions/phpstan
- Owner: yii2-extensions
- License: mit
- Created: 2023-10-06T13:01:36.000Z (over 2 years ago)
- Default Branch: main
- Last Pushed: 2024-02-27T21:57:57.000Z (almost 2 years ago)
- Last Synced: 2025-01-31T08:06:11.142Z (11 months ago)
- Topics: phpstan, yii2, yii2-extensions
- Language: PHP
- Homepage:
- Size: 44.9 KB
- Stars: 2
- Watchers: 1
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
- Code of conduct: .github/CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
PHPStan
Enhanced static analysis for Yii2 applications with PHPStan
Precise type inference, dynamic method resolution, and comprehensive property reflection
## Features

### Installation
```bash
composer require --dev yii2-extensions/phpstan:^0.3
```
### Quick start
Create a `phpstan.neon` file in your project root.
```neon
includes:
- vendor/yii2-extensions/phpstan/extension.neon
parameters:
level: 5
paths:
- src
- controllers
- models
tmpDir: %currentWorkingDirectory%/runtime
yii2:
config_path: config/phpstan-config.php
component_generics:
user: identityClass # Built-in (already configured)
repository: modelClass # Custom generic component
```
Create a PHPStan-specific config file (`config/phpstan-config.php`).
```php
[
app\models\User::class => [
app\behaviors\SoftDeleteBehavior::class,
yii\behaviors\TimestampBehavior::class,
],
],
'components' => [
'db' => [
'class' => yii\db\Connection::class,
'dsn' => 'sqlite::memory:',
],
'user' => [
'class' => yii\web\User::class,
'identityClass' => app\models\User::class,
],
// Add your custom components here
],
];
```
Run `PHPStan`.
```bash
vendor/bin/phpstan analyse
```
### Type inference examples
#### Active Record
```php
// ✅ Typed as User|null
$user = User::findOne(1);
// ✅ Typed as User[]
$users = User::findAll(['status' => 'active']);
// ✅ Generic ActiveQuery with method chaining
$query = User::find()->where(['active' => 1])->orderBy('name');
// ✅ Array results typed as array{id: int, name: string}[]
$userData = User::find()->asArray()->all();
// ✅ Typed based on model property annotations string
$userName = $user->getAttribute('name');
// ✅ Behavior property resolution string
$slug = $user->getAttribute('slug');
```
#### Application components
```php
// ✅ Typed based on your configuration
$mailer = Yii::$app->mailer; // MailerInterface
$db = Yii::$app->db; // Connection
$user = Yii::$app->user; // User
// ✅ User identity with proper type inference
if (Yii::$app->user->isGuest === false) {
$userId = Yii::$app->user->id; // int|string|null
$identity = Yii::$app->user->identity; // YourUserClass
}
```
#### Behaviors
```php
// Behaviors are attached via the `phpstan-config.php` behaviors map (PHPStan only)
/**
* @property string $slug
* @property-read int $created_at
*
* Note: `created_at` is provided by `TimestampBehavior`.
*/
class SoftDeleteBehavior extends \yii\base\Behavior
{
public function softDelete(): bool { /* ... */ }
}
// ✅ Typed based on your configuration
$user = new User();
// ✅ Typed as string (inferred from behavior property)
$slug = $user->getAttribute('slug');
// ✅ Direct property access is also inferred (behavior property)
$slug2 = $user->slug;
// ✅ Typed as int (inferred from behavior property)
$createdAt = $user->getAttribute('created_at');
// ✅ Typed as bool (method defined in attached behavior)
$result = $user->softDelete();
```
#### Dependency injection
```php
$container = new Container();
// ✅ Type-safe service resolution
$service = $container->get(MyService::class); // MyService
$logger = $container->get('logger'); // LoggerInterface (if configured) or mixed
```
#### Header collection
```php
$headers = new HeaderCollection();
// ✅ Typed as string|null
$host = $headers->get('Host');
// ✅ Typed as array
$forwardedFor = $headers->get('X-Forwarded-For', ['127.0.0.1'], false);
// ✅ Dynamic return type inference with mixed default
$default = 'default-value';
$requestId = $headers->get('X-Request-ID', $default, true); // string|null
$allRequestIds = $headers->get('X-Request-ID', $default, false); // array|null
```
#### Service locator
```php
$serviceLocator = new ServiceLocator();
// ✅ Get component with type inference with class
$mailer = $serviceLocator->get(Mailer::class); // MailerInterface
// ✅ Get component with string identifier and without configuration in ServiceMap
$mailer = $serviceLocator->get('mailer'); // MailerInterface (if configured) or mixed
// ✅ User component with proper type inference in Action or Controller
$user = $this->controller->module->get('user'); // UserInterface
```
## Documentation
For detailed configuration options and advanced usage.
- 📚 [Installation Guide](docs/installation.md)
- ⚙️ [Configuration Reference](docs/configuration.md)
- 💡 [Usage Examples](docs/examples.md)
- 🧪 [Testing Guide](docs/testing.md)
## Package information
[](https://www.php.net/releases/8.1/en.php)
[](https://github.com/yiisoft/yii2/tree/2.0.53)
[](https://github.com/yiisoft/yii2/tree/22.0)
[](https://packagist.org/packages/yii2-extensions/phpstan)
[](https://packagist.org/packages/yii2-extensions/phpstan)
## Quality code
[](https://codecov.io/github/yii2-extensions/phpstan)
[](https://github.com/yii2-extensions/phpstan/actions/workflows/static.yml)
[](https://github.com/yii2-extensions/phpstan/actions/workflows/linter.yml)
[](https://github.styleci.io/repos/701347895?branch=main)
## Our social networks
[](https://x.com/Terabytesoftw)
## License
[](LICENSE)