code quality and tooling

Formatting

In professional teams, formatting is usually automated. The human job is to understand why formatting matters, run the project tool, and keep formatting-only changes separate from behaviour changes when possible.

Formatting reveals structure

This code runs, but the structure is hard to see.

PHP example
<?php

declare(strict_types=1);

function total($items){$total=0;foreach($items as $item){if($item['active']){$total+=$item['price'];}}return $total;}

The formatted version makes the loop and condition visible.

PHP example
<?php

declare(strict_types=1);

function activeProductTotal(array $products): int
{
    $total = 0;

    foreach ($products as $product) {
        if ($product['active']) {
            $total += $product['price'];
        }
    }

    return $total;
}

The behaviour is the same. The review effort is lower.

Formatting is not refactoring

Formatting changes layout. Refactoring changes structure while preserving behaviour. Bug fixes change behaviour.

Keep those ideas separate:

  • formatting: spaces, braces, blank lines, wrapping
  • refactoring: extracting a function, renaming for clarity, moving code
  • bug fix: changing a condition, validation rule, calculation, or output

Mixing all three in one diff makes review harder.

Automated tools remove arguments

Projects commonly use tools such as PHP_CodeSniffer, PHP-CS-Fixer, Laravel Pint, or framework presets. These tools enforce the chosen style so the team does not debate spacing in every review.

The command depends on the project, but Composer scripts are common.

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

A developer can then run:

composer format

or check without changing files:

composer format:check

Check mode versus fix mode

Most formatters have two useful modes:

  • check mode reports files that need formatting
  • fix mode rewrites files to match the configured style

CI normally uses check mode so it can fail when code is not formatted. Developers use fix mode locally to update files.

Format only what you touched

In a messy legacy file, formatting the whole file can create a huge diff. Sometimes that is worth doing as a separate cleanup. During a small feature or bug fix, keep the formatting change close to the lines you touched unless the project automatically formats the whole file.

If the formatter rewrites a large file, mention that in the pull request so reviewers know which parts are mechanical.

Do not fight the project style

A project may not use your preferred formatting rules. Follow the repository's configured tool and style.

Look for:

  • composer.json scripts
  • .php-cs-fixer.php
  • phpcs.xml
  • phpcs.xml.dist
  • pint.json
  • CI workflow commands

The local configuration is the source of truth.

Formatting can expose real problems

Sometimes formatting a dense expression makes a bug easier to see.

PHP example
<?php

declare(strict_types=1);

if ($order['paid'] && $order['status'] === 'ready' || $order['priority']) {
    echo 'Ship order';
}

The formatter cannot decide the business rule. It can only make code readable enough for a developer to notice that parentheses may be needed.

PHP example
<?php

declare(strict_types=1);

if (($order['paid'] && $order['status'] === 'ready') || $order['priority']) {
    echo 'Ship order';
}

Formatting supports understanding, but it does not replace careful review.

What to remember

Formatting is a mechanical quality gate. Let tools enforce it, keep formatting changes separate when possible, and follow the repository configuration rather than personal preference.

Before moving on, make sure you can explain the difference between checking formatting and fixing formatting, and why formatting-only diffs should be kept separate from behaviour changes when practical.

Practice

Task: Format An Active Product Total

Format this function without changing its behaviour.

PHP example
<?php

declare(strict_types=1);

function total($items){$total=0;foreach($items as $item){if($item['active']){$total+=$item['price'];}}return $total;}

Requirements

  • Keep the logic the same.
  • Add useful parameter and return types.
  • Use readable indentation and line breaks.
  • Rename the function and variables if it improves clarity.
  • Do not change the calculation rule.
Show solution
PHP example
<?php

declare(strict_types=1);

function activeProductTotal(array $products): int
{
    $total = 0;

    foreach ($products as $product) {
        if ($product['active']) {
            $total += $product['price'];
        }
    }

    return $total;
}

The function still totals only active products. The formatting, names, and types make that rule much easier to review.