Understanding the PSR-12 Standard

Roman Huliak
3 min read2 days ago

--

Photo by Peter Masełkowski on Unsplash

PHP Standards Recommendations (PSRs) are guidelines designed to promote consistency across PHP projects. Among these, PSR-12 (Extended Coding Style Guide) is the modern standard for formatting PHP code. It builds on PSR-2 and incorporates updates for newer PHP features (e.g., type declarations, anonymous classes, and closures). Adhering to PSR-12 ensures code readability, simplifies collaboration, and reduces cognitive friction when working across projects.

Understanding the PSR-12 Standard

PSR-12 defines strict rules for code structure, spacing, indentation, and line length. Here are the key requirements:

1. File Structure

  • Files MUST start with <?php (without a closing ?> tag).
  • Strict type declaration (declare(strict_types=1)) MUST follow the opening tag.
  • Namespace declarations MUST come after the declare statement.
  • Use statements MUST be grouped by root namespace and separated by a blank line.

2. Class and Method Definitions

  • Classes MUST have braces on separate lines.
  • The extends and implements keywords MUST be on the same line as the class name.
  • Method arguments spanning multiple lines MUST be indented once (4 spaces).
  • Visibility modifiers (e.g., public, private) MUST be declared for all properties and methods.

3. Control Structures

  • Control structure keywords (e.g., if, for, foreach) MUST have one space after them.
  • Opening braces MUST be on the same line as the declaration, and closing braces MUST be on a new line.
  • Multi-line conditions MUST split lines after logical operators, with subsequent lines indented once.

4. Spacing and Line Length

  • Lines SHOULD NOT exceed 120 characters.
  • Operators (e.g., =, ., +) MUST be surrounded by spaces.
  • Type declarations (e.g., string $param) MUST NOT have spaces between the type and variable.

5. Anonymous Functions and Closures

  • A space MUST follow the function keyword.
  • The use keyword and opening brace MUST be on the same line.

Real-World Examples

Example 1: Class Definition

<?php

declare(strict_types=1);

namespace Vendor\Package;

use Vendor\Package\FirstNamespace\ClassA;
use Vendor\Package\FirstNamespace\ClassB;
use Vendor\Package\SecondNamespace\ClassC;

class SampleClass extends ParentClass implements InterfaceA, InterfaceB
{
private const MODE_DEBUG = 'debug';

private string $property;

public function __construct(
string $param1,
int $param2,
array $param3 = []
) {
$this->property = $param1;
}

public function doSomething(
int $input,
string $text
): string {
if ($input > 0
&& $text !== ''
) {
return $this->property . $text;
}

return '';
}
}

Example 2: Control Structures

// `if` statement with multi-line conditions
if ($condition1
&& $condition2
&& $condition3
) {
// Code
}

// Anonymous function
$closure = function () use ($var1, $var2): string {
return $var1 . $var2;
};

Best Practices

1. Automate Formatting
Use tools like PHP-CS-Fixer or PHP_CodeSniffer to enforce PSR-12:

php-cs-fixer fix src --rules=@PSR12

2. IDE Configuration
Configure your editor (e.g., PhpStorm, VSCode) to:

  • Use 4 spaces for indentation.
  • Trim trailing whitespace.
  • Set a line length limit of 120 characters.

3. Code Reviews
Include style checks in pull request reviews to catch deviations early.

Common Pitfalls and How to Avoid Them

  • Mixing Spaces and Tabs
    Ensure your editor converts tabs to 4 spaces.
  • Incorrect Use Statement Grouping
    Group use statements by namespace and separate groups with a blank line:
use Vendor\Package\First\{ClassA, ClassB};
use Vendor\Package\Second\ClassC;

use OtherVendor\Package\ClassD;
  • Ignoring Line Length Limits
    Break long lines using method chaining or splitting arguments:
$result = $this->someService->executeLongMethodName(
$argument1,
$argument2,
$argument3
);

Monitoring and Enforcing PSR-12

1. Static Analysis Tools

  • PHP_CodeSniffer:
    Install and run with the PSR-12 ruleset:
composer require squizlabs/php_codesniffer
phpcs --standard=PSR12 src/
  • PHP-CS-Fixer:
    Automatically fix violations:
composer require friendsofphp/php-cs-fixer
php-cs-fixer fix --rules=@PSR12

2. Continuous Integration (CI)

Add a CI step (e.g., GitHub Actions) to block non-compliant code:

# .github/workflows/phpcs.yml
name: PHP_CodeSniffer

on: [push]

jobs:
phpcs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Run PHP_CodeSniffer
run: |
composer install
vendor/bin/phpcs --standard=PSR12 src/

Example for on GitLab here:

3. Pre-commit Hooks

Use tools like pre-commit to run checks before commits:

composer require --dev phpro/grumphp

Conclusion

PSR-12 is a cornerstone of maintainable PHP code. By adopting it, teams reduce style debates, improve code quality, and streamline collaboration. Combine automated tools, CI/CD pipelines, and developer education to enforce the standard effectively. Remember: consistency is key — whether working on legacy projects or new greenfield applications.

--

--

Roman Huliak
Roman Huliak

Written by Roman Huliak

Full Stack Developer with 15 years of experience in ERP systems, skilled in leadership, analysis, and end-to-end development.

No responses yet