spaze/phpstan-disallowed-calls
PHPStan extension to define and enforce a denylist of disallowed function and method calls in your codebase. Catch legacy, unsafe, or unwanted APIs during static analysis with configurable rules and helpful error messages.
Installation Add the package via Composer in your Laravel project:
composer require --dev spaze/phpstan-disallowed-calls
Configure PHPStan
Extend your phpstan.neon configuration to include the extension:
includes:
- vendor/spaze/phpstan-disallowed-calls/extension.neon
Define Disallowed Rules
Create a disallowed-calls.neon file in your project root (or extend the config):
parameters:
disallowedCalls:
functions:
- 'dd'
- 'dump'
- 'abort'
methods:
- 'App\Models\User!methodThatShouldNotBeUsed()'
constants:
- 'App\Constants!SENSITIVE_CONSTANT'
First Use Case Run PHPStan to catch violations:
vendor/bin/phpstan analyse
The tool will flag disallowed calls (e.g., dd() or deprecated methods) in your Laravel app.
Team Onboarding
README.md or CONTRIBUTING.md (e.g., "Never use dd() in production").disallowed-calls.neon as a living standard for code quality.Laravel-Specific Rules
dd() in Controllers/Commands:
parameters:
disallowedCalls:
functions:
- 'dd'
allowIn:
- 'tests/**'
parameters:
disallowedCalls:
methods:
- 'App\Models\Model!fireModelEvent(string $event)'
Conditional Allowances
parameters:
disallowedCalls:
functions:
- 'dd'
allowIn:
- 'tests/Feature/**'
Dynamic Rules via Environment
parameters to toggle rules per environment (e.g., allow dd() in local but not production):
parameters:
disallowedCalls:
functions:
- 'dd'
allowIn:
- '%env(APP_ENV) == "local" ? "app/Http/Controllers/**" : null'
Integration with CI
# .github/workflows/phpstan.yml
- name: PHPStan
run: vendor/bin/phpstan analyse --level=max --error-format=github
Overly Broad Rules
Illuminate\Support\Facades\Log). Instead, target specific methods:
# Bad: Blocks all Log facade calls
parameters:
disallowedCalls:
namespaces:
- 'Illuminate\Support\Facades\Log'
# Good: Blocks only emergency()
parameters:
disallowedCalls:
methods:
- 'Illuminate\Support\Facades\Log!emergency(string $message)'
False Positives in Generics
Model::find()). Use ! to exclude:
parameters:
disallowedCalls:
methods:
- '!App\Models\Model!find(int|string $id)' # Allows find()
Performance Impact
level: max for large codebases may reduce runtime but miss violations. Use selectively:
vendor/bin/phpstan analyse app/Http --level=5
Dynamic Class Names
App\Models\User!method() fail if the class is loaded dynamically (e.g., via new $className). Use regex or avoid dynamic disallowances.Attribute/Keyword Conflicts
global) may break legacy code. Test thoroughly:
parameters:
disallowedKeywords:
- 'global'
Inspect Violations
Use --error-format=json to parse violations programmatically:
vendor/bin/phpstan analyse --error-format=json > violations.json
Temporarily Disable Rules
Comment out rules in disallowed-calls.neon to isolate issues:
# parameters:
# disallowedCalls:
# functions:
# - 'dd'
Leverage PHPStan’s CLI Help List available rules:
vendor/bin/phpstan diagnose
Custom Rules Extend the package by creating a custom PHPStan rule (e.g., for Laravel-specific disallowances):
// app/Rules/DisallowFactoryCallsRule.php
use PHPStan\Rules\Rule;
use Spaze\DisallowedCalls\DisallowedCallsChecker;
class DisallowFactoryCallsRule implements Rule {
public function getNodeTypeNames(): array {
return [MethodCall::class];
}
public function processNode(Node $node, Scope $scope): array {
if ($node instanceof MethodCall && $node->getMethodName() === 'factory') {
return [new Error('Factory calls are disallowed.', $node)];
}
return [];
}
}
Combine with Other Tools
phpstan/extension-installer for zero-config setups:
composer require --dev phpstan/extension-installer
roave/security-advisories to block vulnerable calls.Visual Studio Code Integration
Add to .vscode/settings.json for real-time feedback:
{
"phpstan.executablePath": "vendor/bin/phpstan",
"phpstan.neon": "./phpstan.neon",
"phpstan.enable": true
}
Git Hooks Auto-fix or block commits with disallowed calls:
composer require --dev laravel/git-hooks
Then configure in git-hooks.php:
$hook->add('pre-commit', 'vendor/bin/phpstan analyse --no-progress-bar --error-format=checkstyle | grep -q "ERROR" && exit 1');
How can I help you explore Laravel packages today?