ekino/phpstan-banned-code
PHPStan extension to ban unwanted code in your project. Detects calls like var_dump, dd, eval, exit/die, echo/print, shell exec/backticks, and even “use” imports from Tests in non-test files. Configurable rules for CI enforcement.
composer require --dev ekino/phpstan-banned-code
phpstan.neon:
includes:
- vendor/ekino/phpstan-banned-code/extension.neon
vendor/bin/phpstan analyse app --level=max
Configure phpstan.neon to ban dd(), var_dump, and exit():
parameters:
banned_code:
nodes:
- type: Expr_FuncCall
functions: [dd, var_dump, dump]
- type: Expr_Exit
functions: null
Expected Output: PHPStan errors for any banned function calls, e.g.:
Banned function call: dd($user)
Add to .github/workflows/phpstan.yml:
jobs:
phpstan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: composer install
- run: vendor/bin/phpstan analyse --level=max
Pattern: Fail builds on banned code by default (use non_ignorable: true in config).
Customize extension.neon for Laravel conventions:
parameters:
banned_code:
nodes:
# Laravel-specific
- type: Expr_FuncCall
functions: [dd, dump, artisan, tinker]
# Security risks
- type: Expr_FuncCall
functions: [exec, shell_exec, passthru, system]
# Deprecated PHP
- type: Expr_FuncCall
functions: [mysql_connect, create_function]
# Performance
- type: Stmt_Echo
functions: null
Tip: Use type: Expr_FuncCall for functions, type: Stmt_Echo for statements.
Allow dd() in test files but ban in production:
parameters:
banned_code:
use_from_tests: true # Allows test-specific uses
nodes:
- type: Expr_FuncCall
functions: [dd]
exclude_namespaces: ['Tests\\']
Pattern: Combine use_from_tests with exclude_namespaces for granular control.
Use PHPStan’s level to enforce bans only in production-like environments:
# CI/CD (strict)
vendor/bin/phpstan analyse --level=max
# Local dev (relaxed)
vendor/bin/phpstan analyse --level=5
Load banned functions from .env:
parameters:
banned_code:
nodes:
- type: Expr_FuncCall
functions: %env(BANNED_FUNCTIONS)% # e.g., "dd,var_dump,exec"
Example .env:
BANNED_FUNCTIONS="dd,var_dump,exec,shell_exec"
Phase out deprecated functions incrementally:
parameters:
banned_code:
nodes:
- type: Expr_FuncCall
functions: [mysql_connect, mysql_query] # Phase 1
# - type: Expr_FuncCall # Uncomment after migration
# functions: [create_function] # Phase 2
False Positives in Closures
array_map('dd', $items)).exclude_namespaces or adjust extension.neon to target only named functions.Non-Ignorable Errors
non_ignorable: true), blocking baseline updates.non_ignorable: false if you need to ignore specific instances temporarily.Case Sensitivity
VarDump (camelCase) won’t match var_dump (snake_case).Backtick Shell Execution
shell_exec via backticks (echo id``) may bypass Expr_FuncCall rules.Expr_ShellExec in config:
- type: Expr_ShellExec
functions: null
Performance Impact
echo) can slow down analysis.vendor/bin/phpstan analyse app/Http --level=max
PHPStan Version Mismatch
composer.json:
"require-dev": {
"phpstan/phpstan": "^1.10 || ^2.0 || ^3.0"
}
Inspect AST Nodes
Use PHPStan’s --debug flag to see node types:
vendor/bin/phpstan analyse --debug
Look for entries like Expr_FuncCall: var_dump.
Test Config Incrementally
Start with a single banned function (e.g., dd) and expand:
parameters:
banned_code:
nodes:
- type: Expr_FuncCall
functions: [dd] # Test first
Baseline Exceptions
If errors are non-ignorable, use --generate-baseline to exclude specific files:
vendor/bin/phpstan analyse --generate-baseline
Then edit phpstan.baseline.neon to exclude known issues.
Custom Node Types
For unsupported node types (e.g., Stmt_Declare), check PHPStan’s AST docs or extend the package.
Add Custom Rules Extend the extension by creating a custom PHPStan rule:
use Ekino\PHPStanBannedCode\Rules\BannedNodesRule;
class CustomBannedNodesRule extends BannedNodesRule {
protected function getBannedNodes(): array {
return [
// Add your custom node types/functions
];
}
}
Dynamic Configuration Load banned functions from a database or API:
parameters:
banned_code:
nodes:
- type: Expr_FuncCall
functions: %config(banned_functions)% # From Laravel config
Integration with Laravel Hook into Laravel’s bootstrapping to enforce bans:
// app/Providers/AppServiceProvider.php
public function boot() {
if (app()->environment('production')) {
$this->enforceBannedCodeRules();
}
}
Visual Studio Code Integration Use the PHPStan extension to see banned code errors inline during development.
php-cs-fixer to auto-fix echo/print statements while banning them with PHPStan.# .git/hooks/pre-commit
#!/bin/sh
vendor/bin/phpstan analyse --memory-limit=512M --level=max
BANNED_FUNCTIONS.md to explain why each function is restricted (e.g., security, performance).exclude_namespaces or exclude_files.How can I help you explore Laravel packages today?