Nette Coding Standard
Do you want your PHP code to follow the Nette coding standard without keeping an eye on tabs, braces and blank lines yourself? DressCode checks every file for you and fixes what it finds with a single command.
DressCode is the next generation of the original nette/coding-standard package. It has the Nette coding standard
built in under the name nette. It changes only what breaks the standard and leaves the rest of the file exactly as it
was, so the diff after a fix contains the fixes and nothing else.
Installation
Install DressCode globally using Composer:
composer global require dresscode/dresscode
and make sure your global vendor binaries directory is in your
$PATH environment variable.
DressCode itself runs on PHP 8.4 to 8.6. That is the PHP of the tool, not the PHP your code is written for: your project can
target any version from PHP 8.0 up. DressCode reads it from the php item in the require section of your
project's composer.json and never writes syntax that version does not know.
Configuration
DressCode has no style of its own, so first you tell it which standard your project follows. Create a
dresscode.neon file in the project root:
use:
- nette
paths:
- app
- tests
The use key picks the standard, paths lists the directories to check. Commit the file, so that
everyone on the team, and your CI too, checks the code the same way.
Usage
Let's try it on a class written in a hurry, app/Model/CartService.php, indented with spaces and with the braces
on the wrong lines:
<?php
declare(strict_types=1);
namespace App\Model;
class CartService {
public function getTotal(array $items): float {
$total = 0;
foreach ($items as $item) {
$total = $total + $item['price'] * $item['quantity'];
}
return $total;
}
}
The check command reports what breaks the standard and changes nothing:
dresscode check
app/Model/CartService.php
error 1 `declare(strict_types=1)` must be on the line of the opening tag. file.strictTypes.position
error 2 Expected 1 blank line before the namespace, 2 found. blankLines.beforeNamespace
error 6 Expected 2 blank lines before the class, 1 found. blankLines.beforeDeclaration
error 7:19 Expected a line break before the opening brace. braces.position.class
error 8 Expected the member indented by 1 tab, 4 spaces found. indentation.unit
Then also, on lines 9, 10, 13: Expected the statement indented by 2 tabs, 8 spaces found. indentation.unit
Then also, on line 11: Expected the statement indented by 3 tabs, 12 spaces found. indentation.unit
Then also, on line 12: Expected the closing brace indented by 2 tabs, 8 spaces found. indentation.unit
Then also, on line 14: Expected the closing brace indented by 1 tab, 4 spaces found. indentation.unit
error 8:51 Expected a line break before the opening brace. braces.position.function
error 11:13 The assignment must be written `+=` instead of repeating its target. expressions.assignment.targetInValue
FOUND 13 violations, 6 of them following from others, a fix leaves none in 1 file
Each finding gives the line (and column), says what is wrong, and ends with the name of the setting it breaks, such as
braces.position.class. You will need that name when you want to adjust the standard. The lines starting with
Then also belong to the finding above them; they are what follows from it. The fix command then repairs
everything it can:
dresscode fix
And the class now looks like this:
<?php declare(strict_types=1);
namespace App\Model;
class CartService
{
public function getTotal(array $items): float
{
$total = 0;
foreach ($items as $item) {
$total += $item['price'] * $item['quantity'];
}
return $total;
}
}
Before you run fix for the first time, back up your files, or run it on a clean working tree so you can review the
changes afterwards with git diff.
Adjusting the Standard
Every setting of the standard is a key of the configuration, and your dresscode.neon has the last word on each of
them. Say your project wants one blank line between methods instead of two, and does not want == rewritten to
===:
blankLines:
aroundMethods: 1
expressions:
comparison:
loose: keep
The value keep means “leave it the way the code has it”. What a key is for and what value it has in your
project is printed by dresscode explain blankLines.aroundMethods. And when a single line has a good reason to break
the standard, add a // dresscode:ignore comment to it.
Newer PHP and Nette
DressCode can do more than formatting. Add the modernizations set next to the standard, and it rewrites the code
to what newer PHP offers, such as $user === null ? null : $user->getName() to $user?->getName().
It only goes as far as your composer.json allows:
use:
- nette
- modernizations
When you upgrade the Nette libraries, the dresscode/upgrade-nette package rewrites your code to their new API, see
Upgrading Nette.
Continuous Integration
In a CI pipeline, install DressCode as a standalone project, so you decide which version runs:
- run: composer create-project dresscode/dresscode temp/dresscode ^1
- run: php temp/dresscode/bin/dresscode check
When check finds a violation, it exits with code 1 and the build fails. In GitHub Actions, the
findings show up as annotations right in the pull request.
Moving from Version 3
The original nette/coding-standard package checked the standard with PHP CS Fixer and PHP CodeSniffer, through the
ecs command and the ncs.php and ncs.xml files. It is abandoned in favor of DressCode, and
its version 3 is the last one. To switch, create dresscode.neon as described above, write the adjustments you had in
ncs.php and ncs.xml as its keys, and delete both files. dresscode config lists every key
together with the value it has in your project.
The first dresscode fix will probably touch more files than you expect, because DressCode also fixes some places
that version 3 left alone. Make it a commit of its own, with no other changes.
Everything else, from all the settings to running DressCode in your editor or after every edit an AI agent makes, is in the DressCode manual.