ergebnis/php-cs-fixer-config
Factory-style PHP-CS-Fixer config for projects: choose a versioned ruleset (PHP 5.3–8.3), generate a consistent configuration, and keep coding standards aligned across repositories. Install via Composer and use with friendsofphp/php-cs-fixer.
Install the package in your Laravel project:
composer require --dev ergebnis/php-cs-fixer-config
Create a .php-cs-fixer.php file in your project root:
<?php
declare(strict_types=1);
use Ergebnis\PhpCsFixer\Config;
use PhpCsFixer\Finder;
$ruleSet = Config\RuleSet\Php83::create(); // Match your Laravel project's PHP version
$finder = Finder::create()
->in(__DIR__ . '/app')
->in(__DIR__ . '/config')
->in(__DIR__ . '/database')
->in(__DIR__ . '/routes')
->in(__DIR__ . '/tests')
->exclude('vendor');
$config = Config\Factory::fromRuleSet($ruleSet)
->setCacheFile(__DIR__ . '/.build/php-cs-fixer/.php-cs-fixer.cache')
->setFinder($finder);
return $config;
Add cache directory to .gitignore:
+/.build/
First use case: Run a dry fix to preview changes:
vendor/bin/php-cs-fixer fix --dry-run --diff
# .github/workflows/php-cs-fixer.yml
name: PHP-CS-Fixer
on: [push, pull_request]
jobs:
fix:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
- run: composer install --dev
- run: mkdir -p .build/php-cs-fixer
- run: vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff --verbose
Create a custom Artisan command (app/Console/Commands/FixCodingStandards.php):
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Symfony\Component\Process\Process;
class FixCodingStandards extends Command
{
protected $signature = 'coding-standards:fix';
protected $description = 'Fix coding standards using PHP-CS-Fixer';
public function handle()
{
$process = new Process(['vendor/bin/php-cs-fixer', 'fix', '--config=.php-cs-fixer.php']);
$process->run();
if (!$process->isSuccessful()) {
$this->error($process->getOutput());
return 1;
}
$this->info('Coding standards fixed successfully!');
}
}
$ruleSet = Config\RuleSet\Php83::create()->withRules(Config\Rules::fromArray([
// Laravel-specific overrides
'array_syntax' => ['syntax' => 'short'], // Prefer `[]` over `array()`
'no_unused_imports' => true, // Critical for Laravel's heavy use of facades
'ordered_imports' => ['sort_algorithm' => 'alpha'], // Alphabetical imports
'phpdoc_align' => false, // Disable for Laravel's PHPDoc inconsistencies
'native_function_casing' => false, // Allow `str_*` vs `Str::*` mixed usage
]));
use App\CsFixer\LaravelFixers;
$ruleSet = Config\RuleSet\Php83::create()
->withCustomFixers(Config\Fixers::fromFixers(
new LaravelFixers\FixFacadeUsage(),
new LaravelFixers\FixRouteCasing(),
))
->withRules(Config\Rules::fromArray([
'App\CsFixer\fix_facade_usage' => true,
'App\CsFixer\fix_route_casing' => ['case' => 'snake'],
]));
$finder = Finder::create()
->in(__DIR__)
->exclude('vendor')
->exclude('node_modules')
->exclude('storage')
->exclude('public')
->name('*.php')
->notName('*.blade.php') // Skip Blade templates
->ignoreDotFiles(true)
->ignoreVCS(true);
Cache Directory Permissions
.build/php-cs-fixer is writable:
mkdir -p .build/php-cs-fixer && chmod -R 777 .build/php-cs-fixer
umask 0002 in your CI/CD to avoid permission issues.Rule Conflicts with Laravel Conventions
native_function_casing: Disable if your team mixes str_* and Str::* (e.g., Str::of() vs str_contains()).phpdoc_align: Often conflicts with Laravel’s PHPDoc styles. Disable or adjust:
->withRules(Config\Rules::fromArray([
'phpdoc_align' => ['align' => 'vertical'],
]))
Performance with Large Codebases
--parallel flag for faster runs:
vendor/bin/php-cs-fixer fix --parallel
rm -rf .build/php-cs-fixer/.php-cs-fixer.cache
Dry Run with Verbose Output
vendor/bin/php-cs-fixer fix --dry-run --diff --verbose
--stop-on-failure to halt on first error:
vendor/bin/php-cs-fixer fix --stop-on-failure
Rule-Specific Debugging
vendor/bin/php-cs-fixer fix --rules=@Php83 --dry-run --diff
vendor/bin/php-cs-fixer fix --rules=strict_comparison --dry-run --diff --verbose
Dynamic RuleSets by PHP Version
$phpVersion = PHP_VERSION_ID;
$ruleSet = match (true) {
$phpVersion >= 80300 => Config\RuleSet\Php83::create(),
$phpVersion >= 80200 => Config\RuleSet\Php82::create(),
default => Config\RuleSet\Php81::create(),
};
Environment-Specific Configs
env() to load different rule sets:
$ruleSet = env('APP_ENV') === 'local'
? Config\RuleSet\Php83::create()->withRules(Config\Rules::fromArray([
'strict_comparison' => false, // Relax for local dev
]))
: Config\RuleSet\Php83::create();
Custom Rule Validation
# .git/hooks/pre-commit
#!/bin/sh
vendor/bin/php-cs-fixer validate --config=.php-cs-fixer.php || exit 1
Blade Template Handling
Finder:
->notName('*.blade.php')
laravel-shift/blade-cs-fixer for Blade-specific fixes.Facade Usage Conflicts
no_unused_imports for facades:
->withRules(Config\Rules::fromArray([
'no_unused_imports' => false,
'ordered_imports' => ['sort_algorithm' => 'alpha', 'case_sensitive' => false],
]))
Migration File Formatting
$migrationFinder = Finder::create()->in(__DIR__ . '/database/migrations');
$migrationConfig = Config\Factory::fromRuleSet(Config\RuleSet\Php83::create())
->setFinder($migrationFinder)
->setCacheFile(__DIR__ . '/.build/php-cs-fixer/migrations.cache');
How can I help you explore Laravel packages today?