When would you choose PHP CS Fixer over PHP_CodeSniffer, or run both, to enforce a PHP team's coding style?
answer
- fixer-first versus reporter-first
- PHP config versus XML ruleset
- unfixable conventions need phpcs
- risky modernisation rules
- running both: layout owned by one tool
basics
~20 sPHP CS Fixer suits teams that want every rule fixed automatically, including modernising and risky rewrites; PHP_CodeSniffer suits teams that must also report conventions no tool can fix. Running both works when only one of them owns layout.
solid answer
~40 sThe tools start from opposite ends. **PHP CS Fixer** is fixer-first: every rule rewrites code, the config is PHP (`.php-cs-fixer.dist.php`), and beyond layout it offers modernisation (`@PHP8x5Migration`) and behaviour-changing risky rules; `check` only says a file would change. **PHP_CodeSniffer** is reporter-first: sniffs in a `phpcs.xml.dist` ruleset report errors and warnings with severities and sniff codes, `phpcbf` fixes the subset that is mechanical, and it can flag things no fixer can decide, such as naming or missing doc comments. Many teams run PHP CS Fixer for formatting and modernisation and PHP_CodeSniffer for report-only conventions. The rule is to give **layout to one tool** and exclude those sniffs or rules from the other, or the two will rewrite each other's output.
go deeper
Recall that PHP CS Fixer mainly rewrites code while PHP_CodeSniffer mainly reports it, with phpcbf fixing part of what it reports.
Explain the differences in configuration, suppression and output, and why PHP CS Fixer has no report-only rules.
Show you can combine them safely: one tool owns layout, overlap is excluded, fixer runs first, both versions pinned.
Choose the toolchain from the standard's content: pure layout needs one formatter, judgement-based conventions justify a reporter too.
## Two tools, two starting points Both tools tokenize PHP and enforce a coding standard, and both can target PSR-12 or PER Coding Style, but they were designed around different questions. - **PHP CS Fixer** asks *"what should this code look like?"* and rewrites it. Every rule is a fixer. - **PHP_CodeSniffer** asks *"what is wrong with this code?"* and reports it. Its sniffs raise errors and warnings, and its companion `phpcbf` fixes the violations that a sniff knows how to fix. ## Side by side | Aspect | PHP CS Fixer | PHP_CodeSniffer | |---|---|---| | Primary action | rewrite files (`fix`) | report violations (`phpcs`) | | Report-only mode | `check` / `--dry-run`: lists files that would change, `--diff` shows how | the default; `phpcbf` is the fixing companion | | Unfixable checks | none, since every rule must be able to fix | many, such as naming, doc comments or line length | | Configuration | PHP file returning a `Config` | XML ruleset `phpcs.xml.dist` | | Granularity of findings | per file and rule | per message, with error or warning, severity and a sniff code | | Suppression | `@php-cs-fixer-ignore` file annotation (experimental) | `phpcs:ignore` / `phpcs:disable` by sniff code | | Behaviour-changing rewrites | yes, **risky** rules behind `setRiskyAllowed(true)` | not the tool's focus | | Version modernisation | `@PHP8x5Migration` and similar sets | not the tool's focus | | Custom rules | custom fixers written in PHP | custom sniffs written in PHP | ## When PHP CS Fixer is the better fit - The team wants **zero style discussion**: run `fix`, commit, done. - You want to **modernise syntax** as the minimum PHP version rises, using migration sets. - You are willing to adopt **risky** improvements, like strict comparisons or `declare(strict_types=1)`, in a controlled way. - A formatting check in automation should produce a **diff** the author can apply directly. ## When PHP_CodeSniffer is the better fit - The standard includes conventions that **cannot be fixed automatically**, such as naming rules, required doc comments, forbidden functions with no safe replacement, or line-length limits that need a human to break the line. - You need **graded findings**: warnings that inform but do not block, severities, and suppression by exact sniff code. - An existing ecosystem of shared sniff standards already expresses your rules. ## Running both Combining them is common, typically **PHP CS Fixer for layout and modernisation, PHP_CodeSniffer for report-only conventions**. It works only if the tools do not disagree: 1. **Give layout to one tool.** If both enforce brace placement or spacing with slightly different interpretations, `fix` and `phpcbf` will keep rewriting each other's output. 2. **Exclude the overlap** from the other tool. In a phpcs-for-conventions setup, that means leaving the layout sniffs out of the phpcs ruleset (for example by not including a whole layout standard, or by excluding its whitespace and brace sniffs). 3. **Order the steps.** Run the fixer first, then `phpcs`, so the reporter sees formatted code. 4. **Pin both versions**, because an upgrade of either can change what it enforces. ## Output and suppression in practice The two tools also differ in what a failing check tells the author. `php-cs-fixer check --diff` shows the exact patch to apply, which the author can generate locally with `fix`. `phpcs` shows a list of messages with line numbers and, with `-s`, sniff codes that can be excluded in the ruleset or suppressed with `phpcs:ignore`. Line-level suppression is richer in PHP_CodeSniffer; PHP CS Fixer's exceptions work per file, through the `@php-cs-fixer-ignore` annotation or a rule customisation policy in the config, both still experimental, because its model assumes the fix is normally acceptable. ## A useful way to put it in an interview PHP CS Fixer is the better *formatter*; PHP_CodeSniffer is the better *linter for conventions*. Choosing one is fine when the standard is purely about layout. Once the standard includes rules that need human judgement, PHP_CodeSniffer, alone or beside the fixer, is what can report them.
- What goes wrong if PHP CS Fixer and PHP_CodeSniffer both enforce layout with different settings?Each tool rewrites or flags the other's output: `fix` changes spacing to satisfy its rule, `phpcs` then reports it and `phpcbf` changes it back. The check never stabilises and developers learn to ignore it. One tool must own layout, with the overlapping rules excluded from the other.
- Can PHP CS Fixer enforce a naming convention for methods?Not as a report: every PHP CS Fixer rule must be able to rewrite what it finds, and renaming a method safely needs knowledge of every caller. Naming conventions are the typical reason teams keep PHP_CodeSniffer, whose sniffs can report violations they cannot fix.
saying these in an interview costs you the question
- PHP CS Fixer can report any violation that PHP_CodeSniffer can
- phpcbf fixes everything phpcs reports, so the tools are equivalent
- Running both tools needs no coordination
- PHP CS Fixer is configured with an XML ruleset
- Only PHP_CodeSniffer can check files without modifying them