PHPCS and PHPCBF (PSR-12)
| Install | |
| Simple example | |
| Complex usage | |
| Project config | |
| What it fixed in src/ |
Install
Nothing to install by hand. The first lint-static.sh --tool phpcs run downloads phpcs.phar (and phpcbf.phar when you pass --fix) into ~/.cache/aredel-tools/ and executes it under the php:8.2-cli image. Versions on this site: PHPCS 4.0.4, standard PSR-12:
./scripts/lint-static.sh --tool phpcs --files src/dev/php/linters/phpcs.php
Simple example
Report style violations in one file (read-only, exit 1 on findings):
./scripts/lint-static.sh --tool phpcs --files src/ru/qa/.php/Rblock.php
Auto-fix what is safe to fix ([x] marks in the report) and re-check afterwards:
./scripts/lint-static.sh --tool phpcs --fix --files src/ru/qa/.php/Rblock.php
Complex usage
Several tools at once, staged changes, whole tree, strictness level, saved report, custom standard:
./scripts/lint-static.sh --tool phpstan,psalm,phpcs --files src/ru/qa/.php/
./scripts/lint-static.sh --tool psalm --staged
./scripts/lint-static.sh --tool phpstan --level 2 --all
./scripts/lint-static.sh --tool phpcs --standard PSR2 --files src/dev/php/
./scripts/lint-static.sh --tool phpstan --files src/ru/qa/.php/ --report reports/phpstan-qa
--fix needs an explicit scope (bare whole-tree default is refused, pass --all), fixes [x] violations in place with phpcbf, then re-checks with phpcs. Files still failing land in log/failed_to_fix_<timestamp>.log. [ ] violations are never auto-fixed. Always review with git diff afterwards.
Project config
The shared ruleset is container/phpcs.xml: PSR-12 plus project excludes. Two warnings are suppressed there because fixing them properly is a refactor:
<rule ref="PSR12">
<exclude name="Generic.Files.LineLength"/>
<exclude name="PSR1.Files.SideEffects"/>
</rule>
Long single-string lines (ad HTML blobs) cannot be wrapped safely, and legacy page scripts mix class definitions with top-level echo/require logic. Per-line opt-outs use // phpcs:ignore Generic.Files.LineLength.
What it fixed in src/
- Operator spacing: require_once($root.'/...') to require_once($root . '/...') — 95 hits in src/ru/qa/.php/Page.php alone (410 down to 315 errors).
- Constants: TRUE/FALSE to true/false, trailing whitespace, missing EOF newlines, stray closing ?> tags, blank lines inside use blocks — 1050 errors in 113 files, then 1735 header-spacing errors in 1734 files. Full-tree total went from 3533 to 695 violations.
- By hand, following the PSR1.Methods.CamelCapsMethodName report: 7 methods in src/ru/qa/.php/Rblock.php (show_rblock to showRblock, adv_first_show to advFirstShow, and so on) plus all 12 callers. PHP method calls are case-insensitive, so the rename is runtime-safe.
Left alone on purpose: multi-line call splitting and indentation, brace placement, else if vs elseif, default values before required parameters, and files whose exact bytes matter (BasePage.php/ArticlePage.php are excluded from every --fix run).
Article author: Andrei Olegovich
| 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 |