Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Php Cs Fixer Config Laravel Package

ergebnis/php-cs-fixer-config

A Composer package providing a configuration factory and version-specific rule set factories for friendsofphp/php-cs-fixer, with rule sets covering PHP 5.3 through 8.3.

View on GitHub
Deep Wiki
Context7

Getting Started

Install as a dev dependency — the package never ships in production:

composer require --dev ergebnis/php-cs-fixer-config

Create .php-cs-fixer.php in the project root. The shape is always the same three-step pipeline: pick a rule set → build a config from it → attach your finder and cache.

<?php

declare(strict_types=1);

use Ergebnis\PhpCsFixer\Config;
use PhpCsFixer\Finder;

$ruleSet = Config\RuleSet\Php82::create(); // match your *minimum* supported PHP

$finder = Finder::create()
    ->in(__DIR__)
    ->exclude(['.build', 'storage', 'var', 'vendor']);

$config = Config\Factory::fromRuleSet($ruleSet);

$config->setCacheFile(__DIR__ . '/.build/php-cs-fixer/.php-cs-fixer.cache');
$config->setFinder($finder);

return $config;

Then run it:

mkdir -p .build/php-cs-fixer
vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php --diff --show-progress=dots --verbose

Add /.build/ to .gitignore.

Where to look first: src/RuleSet/ — one class per PHP version (Php53 … Php85), each extending a shared abstract rule set. That directory is the actual product; the Config\Factory just adapts it to PhpCsFixer\Config. Read Php82.php (or whichever you pick) to see exactly which rules are turned on, and skim CHANGELOG.md for "Enabled the … fixer" / "Disabled the … fixer" entries — those are the changes that will rewrite your code.

First use case: brownfield adoption. Run --dry-run first to see the blast radius, commit the mechanical fix separately, then add the CI gate.

Implementation Patterns

Treat the rule set as a base and layer deltas on top. Rule set instances are immutable builders, so composition is additive and explicit:

$ruleSet = Config\RuleSet\Php82::create()
    ->withHeader($licenseHeader)                 // enables HeaderCommentFixer
    ->withRules(Config\Rules::fromArray([        // merged over the base rules
        'mb_str_functions'   => false,
        'strict_comparison'  => false,
        'yoda_style'         => false,
    ]));

Disabling strict_comparison and mb_str_functions is the most common two-line edit in a real Laravel app: strict_comparison rewrites == to === (behaviour change on null/0/'' comparisons), and mb_str_functions requires ext-mbstring and changes string semantics.

Custom fixers follow the same builder, with registration and configuration kept separate:

$ruleSet = Config\RuleSet\Php82::create()
    ->withCustomFixers(Config\Fixers::fromFixers(
        new App\Support\Fixer\FinalInternalClassFixer(),
    ))
    ->withRules(Config\Rules::fromArray([
        'App/final_internal_class' => ['exclude' => ['Tests']],
    ]));

One config file per context in monorepos. Keep a root .php-cs-fixer.php for app/, tests/, routes/, and a separate one (or a second Finder via setPathMode) for packages with their own PHP floor. Do not try to serve two PHP-version rule sets from one config — the fixer output would differ per path.

Automate at three tiers, all pointing at the same config file:

{
  "scripts": {
    "coding-standards": [
      "mkdir -p .build/php-cs-fixer",
      "php-cs-fixer fix --config=.php-cs-fixer.php --diff --show-progress=dots --verbose"
    ],
    "coding-standards:check": [
      "mkdir -p .build/php-cs-fixer",
      "php-cs-fixer fix --config=.php-cs-fixer.php --diff --dry-run --show-progress=dots --verbose"
    ]
  }
}

Locally composer coding-standards (writes), in CI composer coding-standards:check (exit code 8 when files need changing, which fails the job as desired). Cache the .build/php-cs-fixer directory in CI keyed on branch + PHP version + composer.lock hash.

Changed-files-only mode for pre-commit hooks. Running the full fixer on every commit gets slow as the repo grows; either scope by path or run the full pass only in CI:

vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.php \
  --path-mode=intersection app/Http/Controllers/FooController.php

Couple rule-set bumps to PHP-version bumps. When you raise composer.json's php constraint from ^8.1 to ^8.2, change Php81 → Php82 in the same PR. That's the whole migration story for this package, and it keeps the fixer emitting syntax your floor can actually parse.

Gotchas and Tips

  • The rule set version is your minimum PHP, not your CI PHP. Php84 emits 8.4-only constructs (e.g. property hooks, #[\Deprecated]-adjacent rewrites). If a downstream consumer runs 8.1, you've shipped unparseable code. Pick the lowest version you support.
  • Risky rules are enabled by the factory (Factory::fromRuleSet() sets riskyAllowed). That's why you don't pass --allow-risky=yes on the CLI — but it also means the tool will make semantic changes. Review the first diff; don't blanket-git add.
  • The cache directory is not auto-created. setCacheFile('.build/php-cs-fixer/.php-cs-fixer.cache') fails or silently skips caching if the directory doesn't exist. Always mkdir -p before invoking, in every script and in CI.
  • Class-name casing is inconsistent in the docs. The README references Config\RuleSet\Php83 (matching src/RuleSet/), while some changelog entries write Config\Ruleset\Php85. PHP class names are case-insensitive but PSR-4 autoloading on case-sensitive filesystems is not — copy the namespace from the source file, not from the changelog.
  • Header fixer causes mass churn. Turning on withHeader() on an established repo touches every file. Land it as a single mechanical commit, then add that SHA to .git-blame-ignore-revs and configure git blame --ignore-revs-file.
  • Parallel runner is on. The factory configures a parallel run, which is great for speed but means: custom fixers must be autoloadable in worker processes (composer autoload, not a require in the config file), and memory/--sequential is your first debugging step when a custom fixer behaves oddly.
  • Stale cache after custom-fixer changes. The cache key covers rules and config, not your fixer's internals. After editing a custom fixer, delete .build/php-cs-fixer or run with --using-cache=no.
  • Finder::create()->in(__DIR__) is not enough. Explicitly exclude vendor, storage, bootstrap/cache, var, node_modules, .build. Compiled Blade views, generated migrations, and IDE stubs will otherwise be reformatted (or crash the fixer).
  • It fights your IDE formatter. PhpStorm's "Reformat Code" / "Rearrange Code" conflicts with ordered_class_elements, method_argument_space, and brace rules, producing alternating diffs. Disable rearrange-on-save and run composer coding-standards instead — or wire the IDE's external formatter to that script.
  • Minor version bumps can reformat the whole repo. Most releases are dependency bumps, but the "Changed" entries that update friendsofphp/php-cs-fixer and kubawerlos/php-cs-fixer-custom-fixers can shift output. Pin deliberately (^6.54), bump in a dedicated PR, and let CI's --dry-run show the diff before you merge.
  • Extension point inventory — everything you need is a method on the rule set (withHeader, withRules, withCustomFixers) or a setter on the returned PhpCsFixer\Config (setFinder, setCacheFile, setUsingCache, setPathMode, setLineEnding, setIndent). You should never need to subclass or copy rule arrays out of the package.
  • Debugging a single rule: vendor/bin/php-cs-fixer describe <rule> works for built-ins; for custom ones, grep the fixer's getDefinition() to confirm option names before putting them in Rules::fromArray() — a typo'd option name is silently ignored in some versions and throws in others.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo
bernskioldmedia/laravel-harvest
bernskiold/laravel-data-scrubber
bernskiold/laravel-currency-converter
bernskiold/laravel-campaign-monitor
bernskioldmedia/laravel-autotranslate
siberfx/telegram-bot
roy-sandip/laravel-view-extended
gregsphotography/site-builder-core
roy-sandip/laravel-view
anodyne/blade-fluentui-icons
webx-ui/module-catalog-collections