friendsofphp/php-cs-fixer
PHP CS Fixer automatically fixes PHP code to match coding standards. Use built-in rule sets (PER-CS, Symfony, PhpCsFixer) or custom config to unify style, modernize PHP/PHPUnit code, and apply safe or risky migrations. Supports PHP 7.4–8.5.
Installation:
composer require --dev friendsofphp/php-cs-fixer
For Laravel projects, ensure it’s in devDependencies to avoid production bloat.
Initialize Config:
./vendor/bin/php-cs-fixer init
This generates a .php-cs-fixer.dist.php file with a default Symfony rule set—ideal for Laravel.
First Run:
./vendor/bin/php-cs-fixer fix src tests --dry-run
Use --dry-run to preview changes before committing.
| Command | Purpose |
|---|---|
./vendor/bin/php-cs-fixer fix |
Auto-fix files matching config rules. |
./vendor/bin/php-cs-fixer check |
Validate files without modifying them (returns exit code 1 on errors). |
./vendor/bin/php-cs-fixer list-rules |
List all available rules for customization. |
Pre-Commit Hooks:
Use php-cs-fixer in a Git pre-commit hook to enforce consistency:
# .git/hooks/pre-commit
#!/bin/sh
./vendor/bin/php-cs-fixer fix --dry-run --diff || exit 1
Tip: Combine with phpstan or psalm for a full static analysis pipeline.
CI/CD Pipeline: Add to Laravel’s CI (e.g., GitHub Actions):
- name: Run PHP-CS-Fixer
run: ./vendor/bin/php-cs-fixer fix --diff --allow-risky=yes
Use --allow-risky for experimental rules (e.g., @autoPHPMigration).
Editor Integration:
Settings > Tools > PHP > PHP-CS-Fixer.Custom Rule Sets: Extend the default Symfony ruleset for Laravel conventions:
// .php-cs-fixer.dist.php
return (new PhpCsFixerConfig())
->setRules([
'@Symfony' => true,
'no_unused_imports' => true, // Laravel-specific
'ordered_imports' => ['sort_algorithm' => 'alpha'],
'native_function_casing' => true,
'php_unit_method_casing' => ['case' => 'snake_case'], // Laravel tests
]);
Partial Fixes: Target specific directories (e.g., avoid fixing vendor files):
./vendor/bin/php-cs-fixer fix app/Http app/Console --path-mode=intersection
Risky Rules:
Use @autoPHPMigration to modernize PHP versions (e.g., PHP 8.1+):
./vendor/bin/php-cs-fixer fix --rules=@autoPHPMigration --allow-risky=yes
Performance:
->setExclude(['storage/*', 'bootstrap/cache/*'])
--cache-file=.php-cs-fixer.cache.Rule Conflicts:
array_syntax) may break functionality. Test risky rules in a branch first.--dry-run to preview changes before applying.PHP Version Mismatches:
./vendor/bin/php-cs-fixer fix --php-version=8.2
--allow-unsupported-php-version=yes (at your own risk).False Positives:
no_unused_imports may flag Laravel’s dynamic imports (e.g., use Illuminate\Support\Facades\Route;). Exclude them:
->setRules(['no_unused_imports' => ['ignore_relative_imports' => false, 'ignore_missing' => true]])
Verbose Output:
Use -v to debug rule application:
./vendor/bin/php-cs-fixer fix -v
Rule Descriptions: List rules with descriptions:
./vendor/bin/php-cs-fixer describe-rules
Custom Config Validation: Validate your config file:
./vendor/bin/php-cs-fixer validate-ruleset
Custom Rules: Create a custom rule for Laravel-specific patterns (e.g., Blade directives):
// CustomRule.php
use PhpCsFixer\Fixer\FixerInterface;
use PhpCsFixer\Tokenizer\Tokens;
class LaravelBladeSpacingFixer implements FixerInterface { ... }
Register it in .php-cs-fixer.dist.php:
->registerCustomFixers([__DIR__.'/CustomRule.php'])
Rule Sets: Combine multiple rule sets:
->setRules([
'@Symfony' => true,
'@PSR12' => true,
'concat_space' => ['spacing' => 'one'],
])
Parallel Processing:
Speed up large codebases with --parallel:
./vendor/bin/php-cs-fixer fix --parallel
Facade Imports:
Avoid fixing use Illuminate\Support\Facades\Log; to use Log; if your team prefers facades for clarity.
Dynamic Properties:
Rules like no_unused_private_members may flag Laravel’s dynamic properties (e.g., $app). Exclude them:
->setRules(['no_unused_private_members' => false])
Artisan Commands:
Test CS Fixer on generated commands (e.g., php artisan make:command) to avoid breaking changes.
How can I help you explore Laravel packages today?