Ahnii!

Prerequisites: Read PSR-1 first — PSR-12 extends it.

Remember PSR-1’s “house rules” for PHP code? PSR-12 is like the detailed home manual. It extends PSR-1 and replaces the deprecated PSR-2 to provide a comprehensive coding style guide for modern PHP.

Why PSR-12 Matters (2 minutes)

You might think coding style is superficial. But imagine reading a book where every chapter uses different indentation, different quote marks, and different paragraph spacing. It’s exhausting. PSR-12 eliminates these distractions so you can focus on what the code does rather than how it looks.

PSR-12 replaces PSR-2 (now deprecated) and works alongside PSR-1. If PSR-1 covers the “what” (naming, file structure), PSR-12 covers the “how” (formatting, spacing, braces).

Key Style Rules

1. General Code Layout

  • Files MUST use Unix LF line endings.
  • Files MUST end with a single blank line.
  • The closing ?> tag MUST be omitted from files containing only PHP.
  • Lines SHOULD be 80 characters or less.
  • There MUST be one blank line after namespace declarations.
  • Opening braces for classes and methods MUST go on the next line. For control structures (if, for, etc.), braces go on the same line.

2. Class Structure

Here’s an example of a properly structured class:

<?php

declare(strict_types=1);

namespace Vendor\Package;

use Vendor\Package\SomeClass;
use Vendor\Package\AnotherClass as AClass;

class ClassName extends ParentClass implements \ArrayAccess, \Countable
{
    private const VERSION = '1.0';
    
    public function methodName(int $arg1, ?string $arg2): string
    {
        // method body
    }
}

3. Control Structures

Examples of control structures formatted according to PSR-12:

<?php

if ($expr1) {
    // if body
} elseif ($expr2) {
    // elseif body
} else {
    // else body
}

switch ($expr) {
    case 0:
        echo 'First case';
        break;
    default:
        echo 'Default case';
        break;
}

try {
    // try body
} catch (FirstThrowableType $e) {
    // catch body
} finally {
    // finally body
}

Modern PHP Features

1. Type Declarations

Example of using type declarations in method signatures:

<?php

public function processUser(
    User $user,
    ?array $options = null
): ?Response {
    // Implementation
}

2. Attribute Syntax

Example of using attribute syntax in PHP 8:

<?php

#[Route("/api/posts/{id}", methods: ["GET"])]
public function show(#[EntityId] int $id): Response
{
    // Implementation
}

Tools for PSR-12 Compliance

  1. PHP_CodeSniffer Configuration
  2. PHP-CS-Fixer Setup
  3. IDE Integration
    • PhpStorm
    • VS Code with PHP Intelephense

Common Issues and Solutions

  1. Mixed Line Endings
# Check for mixed line endings
$ find . -name "*.php" -exec file {} \;

# Fix with dos2unix
$ find . -name "*.php" -exec dos2unix {} \;
  1. Incorrect Indentation
// Bad
class Foo {
    function bar() {
return true;
    }
}

// Good
class Foo
{
    public function bar(): bool
    {
        return true;
    }
}

Next Steps

In our next post, we’ll explore PSR-13, which defines standards for HTTP message interfaces in PHP. Check out our example repository for the implementation of these standards.

Try It Yourself

Clone the companion repository — the entire project follows PSR-12:

git clone https://github.com/jonesrussell/php-fig-guide.git
cd php-fig-guide
composer install

# Check if code follows PSR-12
composer check-style

# Auto-fix style violations
composer fix-style

See phpcs.xml for the PSR-12 configuration used across the project.

Resources

Baamaapii