PHPCBF: fix style automatically

Contents
Install
Simple auto-fix
Multi-line calls
Prove zero change
[x] versus [ ]
When not to auto-fix

Install

PHPCBF arrives together with PHPCS: same Composer package, same PHAR download, same Docker image. Where phpcs only reports, phpcbf rewrites the file:

composer require --dev phpcsstandards/php_codesniffer vendor/bin/phpcbf --version

Simple auto-fix

The demo file from the previous article reported 12 errors. Ten of them carry the [x] mark — spacing, lowercase constants, header block, trailing whitespace:

phpcbf --standard=PSR12 bad.php

A TOTAL OF 10 ERRORS WERE FIXED IN 1 FILE

Re-checking shows only the two findings without the mark left: they need a human (a namespace and a camelCase rename).

Multi-line calls

Harder-looking reports fix just as mechanically. A legacy page template reported 81 errors of one family: several arguments sharing one line, and the closing parenthesis not on a line by itself:

<?php $result .= ao_card( 'ru', 'edu/literature/witcher/', '/literature/witcher_card', 'Witcher ...', 'Witcher', 'Fan art', 'Book order. Characters.', 'default_icon.png', 'reg', 'png' ) ;

ERROR | [x] Only one argument is allowed per line in a multi-line function call
ERROR | [x] Closing parenthesis of a multi-line function call must be on a line by itself

Fixed on a copy, limited to that sniff family so nothing else moves:

phpcbf --standard=PSR12 --sniffs=PSR2.Methods.FunctionCallSignature Page.php

A TOTAL OF 81 ERRORS WERE FIXED IN 1 FILE

Every call became one-argument-per-line with the bracket on its own line:

$result .= ao_card( 'ru', 'edu/literature/witcher/', '/literature/witcher_card', ... 'png' )

Prove zero change

Three checks, cheapest first. Syntax gate:

php -l Page.php

No syntax errors detected in Page.php

Plain diff shows 164 changed lines — all whitespace, but "all" is a claim. Make it a fact: compare token streams with whitespace and comments stripped. PHP executes tokens, so identical streams mean identical behaviour:

$t = token_get_all($code); // drop T_WHITESPACE, T_COMMENT, T_DOC_COMMENT, compare the rest

tokens before=2597 after=2597
IDENTICAL: semantics unchanged

2597 tokens before, 2597 after, in the same order. The fixer moved only brackets and newlines — a runtime regression is not possible here.

[x] versus [ ]

The mark decides the workflow. [x] is safe for the machine: spacing, casing of constants, header blocks, trailing whitespace, bracket placement. [ ] is always yours: camelCase renames (every caller must change too), argument order constraints, files mixing declarations with executable code.

phpcs --report=full file.php | grep -c "\[x\]"

When not to auto-fix

  1. Huge diffs on stable legacy files: the fix is safe but nobody can review 164 changed lines with confidence — fix new code first.
  2. Files kept byte-identical on purpose: if two copies of a template are compared byte for byte, reformatting one desyncs them. Fix the copies together or not at all.
  3. Mixed findings: run the safe sniff families first (--sniffs=... limits the run), keep reformatting away from logic changes in the same commit.

Always re-run phpcs after phpcbf, review with git diff, and prove behaviour with the token comparison above whenever the diff is too large to read.

Article author: Andrei Olegovich

Related articles
Development with PHP
PHP linters we use
php -l and lint-php.sh
PHPCS: PHP CodeSniffer
phpcs.xml ruleset file
PHPCBF: fix style automatically
wrap-long-lines.sh
PHPStan and Psalm
Banner image

Search this site

Channel @aofeed Chat @aofeedchat

Contacts and cooperation:
I recommend our hosting beget.ru
Write to info@urn.su if you:
1. Want to write an article for our site or translate an article into your native language.
2. Want to place thematically relevant ads on the site.
3. Ads on my site pass maximum censorship. If you see an ad block unsuitable for school-age children, shocking or misleading - please contact us by e-mail
4. Found a mistake, inaccuracy, bug, etc. on the site. ... .......
5. Articles can be shared on social media by clicking a network icon: