phpstan/php-8-stubs
Stub files for PHP 8 built-in functions, classes, and extensions, maintained for PHPStan. Improves static analysis and type inference by providing accurate signatures and phpDoc where native reflection is incomplete or inconsistent.
Install the Package:
composer require --dev phpstan/php-8-stubs
Add the stubs directory to your PHPStan configuration (phpstan.neon):
includes:
- vendor/phpstan/php-8-stubs/src/
Configure PHP Version:
Specify your PHP version in phpstan.neon to ensure correct stubs are loaded:
parameters:
phpVersionId: 80300 # Example: PHP 8.3.0
First Use Case: Run PHPStan on a Laravel controller or service to validate type correctness:
vendor/bin/phpstan analyse app/Http/Controllers/
Focus on catching undefined methods, incorrect return types, or deprecated functions.
Version-Aware Analysis:
Use Php8StubsMap to dynamically load stubs for specific PHP versions (e.g., in CI or multi-version projects):
$map = new \PHPStan\Php8StubsMap(80300); // PHP 8.3.0
$stubPath = $map->classes['datetime'] ?? null; // Path to DateTime stub
Laravel-Specific Integration:
App\Services\PaymentService) by creating manual stubs in stubs/ and including them in phpstan.neon:
includes:
- stubs/
@var annotations in PHPDoc blocks for Laravel’s dynamic properties (e.g., stdClass in facades):
/** @var stdClass $data */
public function handle($data) { ... }
CI/CD Pipeline: Add PHPStan to your GitHub Actions/GitLab CI with stubs enabled:
- name: Run PHPStan
run: vendor/bin/phpstan analyse --level=max app/ --memory=1G
Facade Methods: Stub Laravel facades (e.g., Auth, Cache) by extending phpstan.neon:
parameters:
stubFiles:
- vendor/laravel/framework/src/Illuminate/Foundation/Application.php.stub
(Generate stubs using phpstan/extension-installer or manually.)
Dynamic Return Types: Use union types for Laravel’s polymorphic methods (e.g., Model::find()):
/** @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|null */
public function findUser($id) { ... }
Testing: Run PHPStan against Laravel’s test suite to validate stub accuracy:
vendor/bin/phpstan analyse tests/ --level=max
Version Mismatch:
phpVersionId to your runtime PHP version. Use php -r "echo PHP_VERSION_ID;" to verify.False Positives in Legacy Code:
__get(), __call()) or dynamic properties (e.g., stdClass) trigger errors.@phpstan-ignore-next-line or @phpstan-ignore-line.stubs/App/Models/User.stub).Performance Overhead:
phpstan.neon:
excludeFiles:
- 'vendor/'
- 'tests/'
--parallel and --memory=2G for CI.IDE Conflicts:
phpstan.neon).phpstan:generate-baseline.Deprecated Features:
create_function) as errors.level or suppress specific warnings:
rules:
PHPStan\Rules\DeprecatedFunctionRule: disabled
Inspect Stub Coverage:
Use Php8StubsMap to verify loaded stubs:
$map = new \PHPStan\Php8StubsMap(80300);
print_r($map->classes); // Check if critical classes (e.g., 'datetime') are present.
Generate Baselines: Create a baseline for existing code to avoid overwhelming teams:
vendor/bin/phpstan analyse --generate-baseline app/
Commit baseline.neon to version control.
Isolate Issues: Run PHPStan on a single file to debug:
vendor/bin/phpstan analyse app/Http/Controllers/UserController.php
Custom Stubs:
Create stubs for Laravel-specific classes (e.g., App\Contracts\PaymentGateway) in stubs/ and include them in phpstan.neon:
includes:
- stubs/
PHPStan Extensions: Write custom PHPStan rules to handle Laravel patterns (e.g., dynamic facades):
// Example: Extend PHPStan to ignore Laravel's __call magic methods
final class LaravelMagicMethodRule extends Rule
{
public function getNodeType(): string { return 'method'; }
public function processNode(Node $node): array { ... }
}
Version-Specific Logic:
Use Php8StubsMap to conditionally load stubs based on PHP version in CI:
$phpVersionId = getenv('PHP_VERSION_ID') ?? 80000; // Default to PHP 8.0.0
$map = new \PHPStan\Php8StubsMap($phpVersionId);
Dynamic Facades:
Stub facades by extending Illuminate\Support\Facades\Facade in phpstan.neon:
parameters:
stubFiles:
- stubs/Facades.stub
Example Facades.stub:
<?php
namespace Illuminate\Support\Facades;
class Auth extends \Illuminate\Auth\AuthManager { ... }
Blade Templates: Exclude Blade files from strict analysis (they’re pre-processed):
excludeFiles:
- 'resources/views/**'
Service Container:
For type hints in service bindings, use @mixin in PHPDoc:
/** @mixin \Illuminate\Contracts\Auth\Factory */
class AuthServiceProvider extends ServiceProvider { ... }
How can I help you explore Laravel packages today?