redaxo/php-cs-fixer-config
Official PHP-CS-Fixer config for REDAXO projects, providing ready-made redaxo5() and redaxo6() presets so you can enforce consistent code style with minimal setup. Just install via Composer and point it at your finder.
This is a PHP-CS-Fixer preset, not a runtime library. It ships a Config factory that returns a fully-configured PhpCsFixer\Config (PER-CS 2.0 base + REDAXO conventions + PHP migration set + PHPUnit rules). You can use it in a Laravel app as a ready-made, opinionated style baseline — you just have to accept that the opinions were chosen for REDAXO.
1. Install as a dev dependency (never runtime):
composer require --dev redaxo/php-cs-fixer-config
Requires PHP >= 8.3 on the 3.x line. On PHP 8.1/8.2 Laravel apps you must pin ^2.19 instead.
2. Create .php-cs-fixer.dist.php in the project root:
<?php
use PhpCsFixer\Finder;
use Redaxo\PhpCsFixerConfig\Config;
$finder = (new Finder())
->in(__DIR__)
->exclude(['vendor', 'storage', 'bootstrap/cache', 'node_modules'])
->notPath(['_ide_helper.php', '_ide_helper_models.php'])
;
return Config::redaxo6() // redaxo5() targets PHP 8.x; redaxo6() targets PHP 8.4
->setFinder($finder)
;
3. First run — always dry-run first, on a clean working tree:
vendor/bin/php-cs-fixer fix --dry-run --diff
Then apply, and commit the reformat as a single isolated commit (chore: apply code style) so the noise doesn't pollute review diffs. Add that SHA to .git-blame-ignore-revs.
Where to look first: vendor/redaxo/php-cs-fixer-config/src/Config.php — the factory methods are thin, and everything you'd want to override lives in the rules array they pass to setRules(). Read that array before you write a single override; most "weird" formatting you see is one specific rule you can name and disable.
Composer scripts — the pattern that actually gets used day-to-day:
"scripts": {
"cs": "php-cs-fixer fix",
"cs:check": "php-cs-fixer fix --dry-run --diff"
}
CI gate (fail the build, don't auto-fix on CI):
- run: composer install --prefer-dist --no-interaction
- run: vendor/bin/php-cs-fixer fix --dry-run --diff --no-interaction
Use --using-cache=no in CI unless you cache .php-cs-fixer.cache keyed on the composer lock — a stale cache is the #1 cause of "passes locally, fails in CI".
Pre-commit hook / staged-only fixing. php-cs-fixer has no native --staged; the practical pattern is a Husky/CaptainHook/GrumPHP step that collects staged PHP paths and passes them positionally:
vendor/bin/php-cs-fixer fix --path-mode=intersection $(git diff --name-only --cached --diff-filter=ACM -- '*.php')
Selective overrides — merge, don't replace. setRules() replaces the whole ruleset, so always merge against what the factory produced:
$config = Config::redaxo6();
return $config
->setFinder($finder)
->setRules(array_merge($config->getRules(), [
'concat_space' => ['spacing' => 'one'], // explicit: REDAXO wants spaces around `.`
'yoda_style' => false,
]))
;
Keep every override in one block with a one-line comment on why. Unexplained overrides turn into permanent debt.
Layered configs for monorepos / packages: keep one root .php-cs-fixer.dist.php and create a second file (e.g. .php-cs-fixer.legacy.php) with a narrowed Finder for old directories, run separately. Don't try to encode "this folder is exempt from rule X" — php-cs-fixer can't scope rules per directory in one run.
Local escape hatch: .php-cs-fixer.php (git-ignored) for one-off experiments; the .dist.php file is the team contract.
Don't run this alongside Pint. Pint owns pint.json and its own preset pipeline; two fixers with different concat_space/ordered_imports opinions will produce an infinite flip-flop on every commit. Pick one. If you keep Pint, either drop this package or run it once, copy the resulting rules into pint.json, and uninstall.
IDE integration: point PhpStorm's "PHP CS Fixer" quality tool at vendor/bin/php-cs-fixer and the config file, and enable "check on save". This is where the config earns its keep — nobody runs it manually.
concat_space wants spaces around ., and operator_linebreak forces operators to line-start. Expect a large first diff on any existing Laravel codebase.friendsofphp/php-cs-fixer version, Composer will fail to resolve. Don't add friendsofphp/php-cs-fixer to your own require-dev at a conflicting constraint.Config constructor private. Use the static factories (Config::redaxo5(), ::redaxo6()) only; new Config() will fatal.setFinder() is a hard error, not a fallback to "current directory". Every config file needs one.redaxo6() targets a PHP 8.4 migration set. On a Laravel app running PHP 8.3 in production, this can propose syntax you can't deploy. Use redaxo5() if your composer.json platform PHP is below 8.4.PhpdocLineSpanFixer replacing PhpdocSingleLineVarFixer) mean a composer update can change formatting silently. Pin the package ("redaxo/php-cs-fixer-config": "3.0.*") and bump deliberately; the release notes are the changelog for your code style..blade.php-adjacent plain PHP views, exclude them from the Finder or the diff will be enormous.vendor/bin/php-cs-fixer describe <rule_name> prints the rule's options and examples; -vvv on a fix run names every applied fixer. That beats guessing at a --rules override.--allow-risky: if a fix bails with "risky rules", the factory isn't enabling risky mode for your version — add ->setRiskyAllowed(true) and review the diff carefully, since risky fixers can change behavior..php-cs-fixer.cache and .php-cs-fixer.php both belong in .gitignore.Config.php into your repo and delete the dependency. Budget for that possibility rather than building on its internals.How can I help you explore Laravel packages today?