← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

PHPCS + PHPStan in CI (Workflow Guide)

Style PHP 5.0+ Intermediate
debt(d7/e5/b3/t5)
d7 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'only careful code review or runtime testing' (d7) — the absence of CI enforcement for phpcs/phpstan isn't caught by any tool automatically; it requires someone to inspect the CI config and notice quality gates are missing.

e5 Effort Remediation debt — work required to fix once spotted

Closest to 'touches multiple files / significant refactor in one component' (e5) — quick_fix says configure phpcs and phpstan in composer scripts and CI, which means adding CI workflow files, composer.json scripts, phpstan.neon, phpcs.xml, and likely a baseline for legacy code; more than a one-line patch.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3) — the workflow config lives in CI/composer files and imposes a modest ongoing tax (devs must fix violations, maintain baselines) but doesn't shape the architecture of the application code itself.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap (a documented gotcha)' (t5) — the misconception that local runs suffice is a well-known gotcha; also PHPStan-at-level-0-forever and baseline misuse are documented traps most teams eventually learn.

About DEBT scoring →

Also Known As

PHP CodeSniffer workflow PHPStan CI workflow static analysis workflow

TL;DR

Running PHP_CodeSniffer for style and PHPStan for type/logic errors as separate CI steps — each catching a distinct class of problem.

Explanation

PHP_CodeSniffer (phpcs) enforces formatting rules — PSR-12 compliance, trailing whitespace, line length, brace placement. PHPStan catches logic and type errors that formatting tools miss — wrong return types, null dereferences, dead code. Run them as separate CI steps so failures are clearly attributed. Recommended CI pipeline: composer install → phpcs --standard=PSR12 src/ → phpstan analyse src/ --level=6 → phpunit. Use phpcbf (the fixer companion to phpcs) as a pre-commit hook so formatting issues never reach CI. Store PHPStan configuration in phpstan.neon, baseline in phpstan-baseline.neon for legacy code. Run both in parallel where CI supports it. Add psalm as a third layer for teams wanting maximum type safety coverage.

Common Misconception

Running PHPStan and PHP CodeSniffer locally is sufficient quality assurance. Without CI enforcement both tools become opt-in — developers under time pressure skip them. CI gates that fail on any violation are the only reliable way to prevent standard drift.

Why It Matters

Running PHP_CodeSniffer and PHPStan together in CI catches both style violations and type errors before code is merged — making quality gates automatic rather than relying on reviewer memory.

Common Mistakes

  • Running tools only locally — developers skip them under pressure; CI enforces them for everyone.
  • Starting PHPStan at level 0 and never increasing — it provides minimal value at the lowest level.
  • Not using a baseline for legacy code — a fresh PHPStan run on old code produces thousands of errors; baseline incrementally.
  • Fixing PHPCS warnings by suppressing them rather than correcting the code.

Code Examples

✗ Vulnerable
# CI pipeline without static analysis:
steps:
  - run: composer test    # Tests only — no style or type checking
  # No phpcs, no phpstan
  # Type errors and style violations merge undetected

# With quality gates:
steps:
  - run: vendor/bin/phpcs --standard=PSR12 src/
  - run: vendor/bin/phpstan analyse --level=8 src/
  - run: composer test
✓ Fixed
# CI workflow — code quality gates

# phpcs.xml
<?xml version="1.0"?>
<ruleset name="Project">
    <arg name="basepath" value="."/>
    <arg name="extensions" value="php"/>
    <rule ref="PSR12"/>
    <exclude-pattern>vendor/*</exclude-pattern>
    <exclude-pattern>database/migrations/*</exclude-pattern>
</ruleset>

# phpstan.neon
parameters:
    level: 6
    paths:
        - src
        - tests
    ignoreErrors:
        - '#Call to an undefined method Illuminate#'

# composer.json scripts
"ci": ["@lint", "@analyse", "@test", "@audit"]
"lint":    "phpcs"
"analyse": "phpstan analyse"

# .github/workflows/ci.yml
- run: composer lint
- run: composer analyse
- run: composer test

Added 15 Mar 2026
Edited 22 Mar 2026
Views 51
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 1 ping W 1 ping T 0 pings F 3 pings S 1 ping S 0 pings M 0 pings T 1 ping W 0 pings T 1 ping F 0 pings S 2 pings S 2 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 0 pings S 1 ping S 1 ping M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 9 Perplexity 5 SEMrush 5 ChatGPT 5 Scrapy 5 Google 4 Ahrefs 4 Unknown AI 2 Claude 2 Meta AI 1 PetalBot 1
crawler 39 crawler_json 4
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Low
⚡ Quick Fix
Run phpcs for style and phpstan for logic in CI — they catch different problems; configure both in composer scripts so developers run the same checks locally that CI runs
📦 Applies To
PHP 5.0+ web cli
🔗 Prerequisites
🔍 Detection Hints
Only one of phpcs or phpstan in CI; no local equivalent of CI quality checks; style violations reaching code review
Auto-detectable: ✓ Yes phpcs phpstan php-cs-fixer composer
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Low ✓ Auto-fixable Fix: Low Context: File


✓ schema.org compliant