code quality and tooling

PHP-CS-Fixer

PHP-CS-Fixer is a formatter for PHP. It rewrites code to match a configured set of style rules. Where PHP_CodeSniffer is often used as a checker with a separate fixer, PHP-CS-Fixer is primarily built around fixing code automatically.

In real projects, PHP-CS-Fixer keeps diffs consistent and removes formatting debate from pull requests.

Running the fixer

In a Composer project, the command is usually:

vendor/bin/php-cs-fixer fix

That changes files in place based on the project configuration.

To check what would change without modifying files, use dry-run mode:

vendor/bin/php-cs-fixer fix --dry-run --diff

This is the kind of command CI often runs.

Configuration file

Projects commonly store configuration in .php-cs-fixer.dist.php.

PHP example
<?php

use PhpCsFixer\Config;
use PhpCsFixer\Finder;

$finder = Finder::create()
    ->in(__DIR__ . '/src')
    ->in(__DIR__ . '/tests');

return (new Config())
    ->setRules([
        '@PSR12' => true,
        'array_syntax' => ['syntax' => 'short'],
    ])
    ->setFinder($finder);

This file is PHP code. It returns a config object with rules and a finder that chooses which files to format.

Rule sets and rules

PHP-CS-Fixer supports rule sets such as @PSR12, plus individual rules.

PHP example
<?php

return (new PhpCsFixer\Config())
    ->setRules([
        '@PSR12' => true,
        'strict_param' => true,
    ]);

Some rules are purely formatting. Some are more opinionated. Some are considered risky because they may change behaviour in edge cases. Be cautious with risky rules and follow the project's existing config.

Fix mode versus dry-run mode

Use fix mode locally when you want the tool to rewrite files:

vendor/bin/php-cs-fixer fix

Use dry-run mode when you want to check whether files are already formatted:

vendor/bin/php-cs-fixer fix --dry-run --diff

Dry-run mode should not change files. The diff shows what the fixer would change.

Composer scripts

Teams often wrap the commands.

{
  "scripts": {
    "format": "php-cs-fixer fix",
    "format:check": "php-cs-fixer fix --dry-run --diff"
  }
}

Then developers run:

composer format
composer format:check

Use the project scripts when they exist.

Review the diff

Automatic formatting is mechanical, but you still need to review the diff before committing.

Look for:

  • unexpectedly large changes
  • files you did not intend to touch
  • risky rules changing more than layout
  • generated files that should be excluded
  • formatting mixed with unrelated behaviour changes

If a formatter changes many unrelated files, consider committing that separately from feature work.

PHP-CS-Fixer and PHP_CodeSniffer

The tools overlap, but they are not identical.

PHP_CodeSniffer is commonly used to detect coding-standard violations and can fix many with phpcbf. PHP-CS-Fixer is strongly focused on applying fixer rules and has its own configuration style.

Use whichever tool the project already uses. Do not add a second formatter unless the team has agreed on how the tools interact.

What to remember

PHP-CS-Fixer rewrites PHP code to match configured style rules. The key professional habits are running the project command, using dry-run in CI, committing the shared config, and reviewing the formatter diff.

Before moving on, make sure you can explain the difference between fix and fix --dry-run --diff.

Practice

Task: Configure PHP-CS-Fixer

Write a minimal PHP-CS-Fixer setup for a project that formats src and tests.

Requirements

  • Show a .php-cs-fixer.dist.php config.
  • Use the @PSR12 rule set.
  • Include one extra rule that prefers short array syntax.
  • Give the command to fix files.
  • Give the command to check formatting without changing files and show a diff.
Show solution

.php-cs-fixer.dist.php

PHP example
<?php

use PhpCsFixer\Config;
use PhpCsFixer\Finder;

$finder = Finder::create()
    ->in(__DIR__ . '/src')
    ->in(__DIR__ . '/tests');

return (new Config())
    ->setRules([
        '@PSR12' => true,
        'array_syntax' => ['syntax' => 'short'],
    ])
    ->setFinder($finder);

Fix files:

vendor/bin/php-cs-fixer fix

Check without changing files and show a diff:

vendor/bin/php-cs-fixer fix --dry-run --diff

The config should be committed so every developer and CI uses the same formatting rules.