What is PHP 8 Constructor Property Promotion?
PHP 8 introduced Constructor Property Promotion, a syntax-shorcutting feature designed to significantly reduce boilerplate code when declaring and initializing class properties. This article explains how constructor property promotion works, compares it with traditional PHP syntax, and details the key rules and best practices for using it in modern PHP applications.
The Boilerplate Problem in PHP 7 and Earlier
Before PHP 8, defining a simple class with properties required repeating the property name at least four times: once for the property declaration, once for the constructor parameter, once for the assignment, and inside the docblocks or type hints.
Here is a typical PHP 7.x example:
class User {
public string $name;
public string $email;
public function __construct(string $name, string $email) {
$this->name = $name;
$this->email = $email;
}
}This approach leads to redundant code, especially in classes with many dependencies or properties, such as Data Transfer Objects (DTOs) or Controller classes.
The PHP 8 Solution: Constructor Property Promotion
Constructor property promotion allows you to combine the property declaration, the constructor parameter, and the property assignment into a single statement.
By prefixing a constructor parameter with a visibility keyword
(public, protected, or private),
PHP 8 automatically promotes that parameter to a class property with the
same name and assigns the passed value to it.
Here is the exact same User class rewritten using PHP 8
syntax:
class User {
public function __construct(
public string $name,
public string $email,
) {}
}When PHP compiles this code, it transpiles it under the hood to the traditional, verbose version. The class body can remain entirely empty if no other initialization logic is required.
Key Rules and How to Use It
To use constructor property promotion effectively, you must follow several specific syntax rules:
1. Explicit Visibility is Required
Promotion only triggers if the constructor parameter is prefixed with
a visibility keyword (public, protected, or
private). If you omit the visibility keyword, the parameter
behaves like a standard, non-promoted constructor argument.
2. Type Hinting and Default Values
Promoted properties fully support type declarations and default values.
class Product {
public function __construct(
public string $name,
public float $price = 0.0,
) {}
}3. Combining Promoted and Standard Properties
You can mix promoted properties and standard properties within the same class and constructor.
class Order {
public string $status;
public function __construct(
public int $id,
string $initialStatus = 'pending'
) {
$this->status = $initialStatus;
}
}4. No Duplication Allowed
You cannot declare a class property and also promote a constructor parameter with the same name. Doing so will result in a fatal syntax error.
class InvalidClass {
public string $name; // Error: Cannot redeclare promoted property
public function __construct(public string $name) {}
}5. Readonly Properties (PHP 8.1+)
In PHP 8.1 and later, you can combine property promotion with the
readonly modifier. This is highly useful for creating
immutable DTOs.
class Configuration {
public function __construct(
public readonly string $apiKey,
public readonly int $timeout,
) {}
}