PHP Typed Properties: How They Work

This article explores the implementation and behavior of typed properties introduced in PHP 7.4 and refined in subsequent versions. You will learn how to declare type hints for class properties, understand how PHP handles the uninitialized state, and discover how this feature improves type safety and code readability in modern PHP development.

Declaring Typed Properties

Starting in PHP 7.4, you can declare types for class properties. This ensures that any value assigned to a property strictly matches its defined type, preventing type-related bugs.

Here is a basic example of typed properties in a class:

class User {
    public int $id;
    public string $name;
    public ?string $email; // Nullable string
}

In this example, $id must always be an integer, $name must be a string, and $email can either be a string or null.

Supported Types

PHP supports a wide range of types for class properties, including:

Note: The types void and callable are not supported as property types.

The Uninitialized State

When a typed property is declared without a default value, it starts in an uninitialized state. This is different from having a value of null.

class Product {
    public string $sku;
}

$product = new Product();
// Accessing $product->sku here will throw a Typed Property Error

If you attempt to read a typed property before it has been initialized (either via a default value or inside the constructor), PHP throws an Error exception:

Fatal error: Uncaught Error: Typed property Product::$sku must not be accessed before initialization

To check if a property has been initialized without triggering an error, you can use the isset() function:

if (isset($product->sku)) {
    echo $product->sku;
}

Type Coercion and Strict Types

By default, PHP will attempt to coerce values to the declared property type if strict types are not enabled.

class Profile {
    public int $age;
}

$profile = new Profile();
$profile->age = "30"; // Coerced to integer 30

However, if you declare declare(strict_types=1); at the top of your file, PHP will throw a TypeError if you attempt to assign a value that does not match the exact type definition.

Readonly Properties (PHP 8.1 and Later)

PHP 8.1 introduced the readonly modifier for typed properties. A readonly property can only be initialized once, usually in the constructor, and cannot be modified afterward.

class Book {
    public readonly string $isbn;

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

Any attempt to modify $isbn after its initial assignment will result in a Fatal error.