PSR-12 compliance
January 13, 2025 ยท View on GitHub
This document describes what happens when strict PSR-12 / PER Coding Style
compliance is enabled via the --psr12 option or the pretty-php API (e.g.
Formatter::withPsr12()).
It also explains how (and why) pretty-php's default style is not quite 100%
compliant.
Options
The equivalent of the following command-line options are applied when strict PSR-12 compliance is enabled:
--space=4--eol lf--heredoc-indent hanging
And these are ignored:
--one-true-brace-style--no-sort-imports
Internally, values assigned to Formatter properties are as follows:
InsertSpaces:trueTabSize:4PreferredEol:"\n"PreserveEol:falseHeredocIndent:HeredocIndent::HANGINGOneTrueBraceStyle:falseExpandHeaders:truePsr12:trueNewlineBeforeFnDoubleArrow:true
Rules
In strict PSR-12 mode, these rules are enabled and cannot be disabled:
sort-imports|SortImports(sort order is not specified, but import statements must be grouped by class, then function, then constant as per PSR-12, section 3)strict-expressions|StrictExpressionsstrict-lists|StrictListsdeclaration-spacing|DeclarationSpacing
And these cannot be enabled:
preserve-one-line|PreserveOneLineStatementssemi-strict-expressions|SemiStrictExpressionsalign-lists|AlignLists
Behaviours
The following behaviours apply only when strict PSR-12 compliance is enabled.
Declare statements
Rule: StandardSpacing
With or without a semicolon after the closing parenthesis, the following is collapsed to one line as per PSR-12, section 3:
<?php declare(strict_types=1) ?>
Otherwise, header blocks are formatted as prescribed:
<?php
/**
* Header
*/
declare(strict_types=1);
namespace Vendor\Package;
pretty-php's default style departs from the standard to collapse openingdeclarestatements as below. This is to prevent wasteful use of vertical space at the beginning of every file in projects with headers like this:<?php declare(strict_types=1); /** * Header */ namespace Vendor\Package;
Control structure expressions
Rule: StrictExpressions
Control structure expressions that break over multiple lines are moved to the start of a line, as per PSR-12, section 5:
<?php
// Before
if ($foo || $bar) {
baz();
}
if ($foo ||
$bar) {
baz();
}
// After
if ($foo || $bar) {
baz();
}
if (
$foo ||
$bar
) {
baz();
}
Because
pretty-phpuses hanging indentation instead of vertical space for visual separation between adjacent code, neitherStrictExpressionsnorSemiStrictExpressionsare mandatory by default.
Arrow functions
Arrow functions that break over multiple lines are arranged as per PER Coding Style 2.0, section 7.1:
<?php
$foo = fn()
=> bar();
pretty-php's default style departs from the standard to minimise the horizontal space required for arrow function expressions:<?php $foo = fn() => bar();
Heredocs and nowdocs
Rule: StandardSpacing
Newlines before heredocs and nowdocs are suppressed, and unconditional heredoc indentation is enforced as per PER Coding Style 2.0, section 10:
<?php
$foo = [
'bar',
<<<EOF
Content
EOF,
];
$baz = <<<EOF
Content
EOF;
pretty-php's default style does not apply indentation to heredocs in contexts where there is no ambiguity without it:$foo = <<<EOF Content EOF; $baz = <<<EOF Content EOF;
Exceptions
Rule: OperatorSpacing
Spaces are added between exceptions and | in catch blocks.
pretty-php's default style collapses whitespace in this context for consistency with union type formatting.
Comments
Rule: PlaceComments
Comments beside the closing brace of a class / interface / trait / enum
are moved to the next line.
pretty-php's default style departs from the standard for consistency with its approach to comments beside code in other contexts. Varying comment placement beside some close braces but not others makes formatter behaviour seem arbitrary and reduces readability.