How to write Coding Guidelines in PHP

Reading Time: 4 minutes

Writing PHP applications in a team requires clear guidelines and a lot of alignment. In my book, Clean Code in PHP, I dedicated a full chapter, Working in a team, on how to write PHP software together with other developers.

Coding Guidelines are easy to introduce yet still compelling, so it makes them a perfect tool to introduce to early. Together with your team, you agree on standards to write your software.

This is not only important for onboarding new colleagues, which surely will be happy to see how the new team they will be part of writes the code. It is also useful during Code Reviews—once agreed on a rule, you don’t need to argue about in anymore.

The following article is supposed to give you some inspiration for your team’s guidelines. Please don’t consider them as the single truth or set in stone: every software team is different, and what works for one team, might not work for the other.

Naming Conventions

Services, Repositories, and Models

Written in UpperCamelCase. Use the type as suffix.

Examples:

  • UserService
  • ProductRepository
  • OrderModel

Events

Written in UpperCamelCase. Use the correct tense to indicate if the event is fired before or after the actual event.

Examples:

  • DeletingUser is the event before the deletion
  • DeleteUser is the actual event
  • UserDeleted is the event after the deletion

Properties, Variables, and Methods

Written in lowerCamelCase.

Examples:

  • $someProperty
  • $longerVariableName
  • $myMethod

Tests

Written in lowerCamelCase. Use the word test as a prefix.

Examples:

  • testClassCanDoSomething()

Traits

Written in UpperCamelCase. Use the adjective to describe what the Trait is used for.

Examples:

  • Loggable
  • Injectable

Interfaces

Written in UpperCamelCase. Use the word Interface as suffix.

Examples:

  • WriterInterface
  • LoggerInterface

General PHP conventions

Comments and DocBlocks

Since PHP 8, most information in DocBlocks can be reused by native PHP features, particularly type hints. Redundant or even useless DocBlocks simply waste time of the developers, while wrong DocBlocks can cause confusion and bugs.

// Avoid redundant DocBlocks

/**
 * @param int $property
 * @return void 
 */
public function setProperty(int $property): void { 
    // ... 
}

// Avoid useless Docblocks

/**
 * @param $property
 */
public function setProperty(int $property): void { 
    // ... 
}

// Example for wrong DocBlocks

/**
 * @param string $property
 */
public function setProperty(int $property): void { 
    // ... 
}

Ternary Operators

Every part should be written in a single line to increase readability. Exceptions can be made for very short statements.

// Example for short statement
$isFoo ? ‘foo’ : ‘bar’;

// Usual notation
$isLongerVariable
    ? ‘longerFoo’

    : ‘longerBar’;

Do not use nested ternary operators, as they are hard to read and debug.

// Example for nested operators
$number > 0 ? 'Positive' : ($number < 0 ? 'Negative' : 'Zero');

Constructor

Use Constructor Property Promotion for shorter classes, if working with PHP 8+.

// Before PHP 8+
class ExampleDTO
{
    public string $name;

    public function __construct(
        string $name
    ) {
        $this->name = $name;
    }
}

// Since PHP 8+
class ExampleDTO
{
    public function __construct(
        public string $name,
    ) {}
}

Arrays

Always use the short array notation and keep the comma after the last entry.

// Old notation
$myArray = array(
    'first entry',
    'second entry'
);

// Short array notation
$myArray = [
    'first entry',
    'second entry',
];

Control structures

Always use brackets, even for one-liners.

// Bad
if ($statement === true)
    do_something();

// Good
if ($statement === true) {
    do_something();
}

Avoid else statements and return early, as this is easier to read and reduces the complexity of your code.

// Bad
if ($statement) {
    // Statement was successful
    return;
} else {
    // Statement was not successful
    return;
}

// Good
if (!$statement) {
    // Statement was not successful
    return;
}

// Statement was successful
return;

Exception Handling

Empty catch blocks should be avoided, as they silently swallow error messages and thus can make it difficult to find bugs. Instead, log the error message or at least write a comment which explains why the exception can be ignored.

// Bad
try {
    $this->someUnstableCode();
} catch (Exception $exception) {}

// Good
try {
    someUnstableCode();
} catch (Exception $exception) {
    $this->logError($exception->getMessage());
}

Architectural patterns

Coding Guidelines are not limited on how to format code or name elements. They can also help you to control how the code is written in an architectural sense.

Fat models, skinny controllers

If the Model View Controller (MVC) pattern is used, the business logic should be located inside models or similar classes, like services or repositories. Controllers should only contain as little code as possible which is required to receive or transfer data between the views and the models.

Framework-agnostic code

In the context of the fat models, skinny controllers approach, you will probably come across the term framework-agnostic business logic. It means that the code that contains your business rules should use features of the underlying framework as few as possible. This makes framework updates or even migrations to other frameworks much easier.

Single responsibility principle

Classes and methods should only have one responsibility, as stated by the Single Responsibility Principle.

Framework guidelines

  • How to access the database?
  • How to configure routes?
  • How to register new services?
  • How is Authentication handled within your project?
  • How should errors or other debug information be logged?
  • How to create and organize view files?
  • How to handle translations?

Since the answers to these questions highly depend on the used framework, we cannot give you recommendations here. You will need to set them up together with your team. In the next section, we will give you some ideas on how to do that.

Leave a Reply

Your email address will not be published. Required fields are marked *

I accept the Privacy Policy

This site uses Akismet to reduce spam. Learn how your comment data is processed.