Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Code quality

Code is read more often than it is written. When the whole project is formatted the same way and a program finds the obvious mistakes, it is easier to work with, alone or in a team. There is a shared coding standard for that, and tools that enforce it by themselves.

The PSR-12 standard

PSR-12 is the community's agreement on how to format PHP code. The main rules:

RuleExample
Indentation is 4 spacesNot a tab
Class names in PascalCaseOrderService
Method and variable names in camelCasegetTotal(), $orderId
Constants in capital lettersMAX_ITEMS
The brace of a class or method on a new lineSee below
The brace of if, for, foreach on the same lineSee below
One class — one filesrc/OrderService.php
<?php
 
declare(strict_types=1);
 
class OrderService
{
    private const MAX_ITEMS = 10;
 
    public function canAdd(int $count): bool
    {
        if ($count >= self::MAX_ITEMS) {
            return false;
        }
 
        return true;
    }
}
 
echo (new OrderService())->canAdd(3) ? 'allowed' : 'not allowed'; // allowed

Automatic formatting

There is no need to watch the formatting by hand — PHP-CS-Fixer does it:

composer require --dev friendsofphp/php-cs-fixer
vendor/bin/php-cs-fixer fix src

The command fixes indentation, spaces and braces in every file of the src folder.

Static analysis

A static analyser reads code without running it and finds mistakes that would otherwise show up only for a visitor. The best known is PHPStan:

composer require --dev phpstan/phpstan
vendor/bin/phpstan analyse src --level=5

There are ten levels — from the crudest mistakes to very strict checks. You start low and raise the level gradually.

What the analyser finds

<?php
 
function findUser(int $id): ?array
{
    return $id === 1 ? ['name' => 'Anna'] : null;
}
 
$user = findUser(2);
 
echo $user['name'] ?? 'not found'; // not found

Without the ?? operator the line echo $user['name'] would run with a warning as soon as a user is not found. PHPStan notices that in advance: the function may return null, and the code does not account for it. It likewise finds calls to non-existent methods, wrong argument types and unreachable code.

Hints for the analyser

The more precise the types, the more mistakes the analyser sees. What a PHP type cannot express is written in a comment:

<?php
 
/**
 * @param array<int, string> $names
 * @return array<string, int>
 */
function countLetters(array $names): array
{
    $result = [];
 
    foreach ($names as $name) {
        $result[$name] = strlen($name);
    }
 
    return $result;
}
 
echo json_encode(countLetters(['Anna', 'Peter'])); // {"Anna":4,"Peter":5}

Composer scripts

To avoid remembering long commands, they are written in composer.json:

{
    "scripts": {
        "format": "php-cs-fixer fix src",
        "analyse": "phpstan analyse src --level=5",
        "test": "phpunit",
        "check": ["@format", "@analyse", "@test"]
    }
}
composer check

One command formats the code, checks it and runs the tests. It is run before every push.

Common mistake

Turning the analyser on at a high level in an old project and getting thousands of remarks is a sure way to abandon it. Start at level 0 or 1, fix what was found, then raise the level. For a large old codebase PHPStan can record existing remarks in a baseline file and demand cleanliness only from new code.

Thanks for reading!

Donate to the site — we work hard for you.