PHP
Rules marked [enforced] are caught automatically by PHP Code Sniffer (ddev composer test) or PHPStan (ddev composer run-script phpstan).
Opening and closing tags [enforced]
Section titled “Opening and closing tags [enforced]”Use <?php for logic and <?= for inline output. Never use the short tag <? or the ASP-style tag <%. Omit the closing ?> at the end of every file — a trailing newline after it can cause unexpected output.
// Good — class file, no closing tag<?php
namespace App\Hook;
class ExampleHook{}// Good — inline output with short-echo tag<h1><?= esc_html($title) ?></h1>// Bad — short tag<? echo esc_html($title) ?>
// Bad — closing tag at end of file<?php
class ExampleHook{}?>Indentation [enforced]
Section titled “Indentation [enforced]”Use 4 spaces.
Array syntax
Section titled “Array syntax”Use short array syntax [] instead of array().
// Good$items = ['foo', 'bar'];
// Bad$items = array('foo', 'bar');String quotes
Section titled “String quotes”Use single quotes for plain strings. Use double quotes only when the string contains a variable or an escape sequence.
// Good$greeting = 'Hello';$message = "Hello, {$name}";
// Bad$greeting = "Hello";Type declarations [enforced]
Section titled “Type declarations [enforced]”Always declare parameter types and return types. PHPStan will catch missing type declarations on new code.
// Goodpublic function getTitle(int $id): string{ return get_the_title($id);}
// Badpublic function getTitle($id){ return get_the_title($id);}Use ?Type for nullable values:
public function findPost(int $id): ?Timber\Post{ return Timber::get_post($id) ?: null;}Naming conventions
Section titled “Naming conventions”| What | Convention | Example |
|---|---|---|
| Class | PascalCase | TeamMemberHook |
| Method | camelCase | getTeamMembers() |
| Variable | camelCase | $teamMembers |
| Constant | UPPER_SNAKE_CASE | PostTypeConstant::TEAM_MEMBER |
| File | Match class name | TeamMemberHook.php |
Class structure
Section titled “Class structure”Order class members as follows: constants → properties → constructor → public methods → protected methods → private methods.
<?php
namespace App\Hook;
use App\Lib\Contracts\HookContract;
class TeamHook implements HookContract{ private const CACHE_KEY = 'team_members';
private int $limit;
public function __construct(int $limit = 10) { $this->limit = $limit; }
public function register(): void { add_action('init', [$this, 'registerPostType']); }
public function registerPostType(): void { // implementation }}PSR-2 [enforced]
Section titled “PSR-2 [enforced]”The project follows PSR-2 for everything not covered above. PHP Code Sniffer enforces this automatically.
If you use VSCode, install the phpcs extension for inline feedback.
Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.
Kernighan
If you need a comment to explain what a piece of code does, consider rewriting it instead.

