← lessons

Implement property hooks in PHP 8.4

Video Lesson

PHP 8.4 introduces a new feature called property hooks, which allows you to modify class property values with special hooks.

Lesson Content

PHP 8.4 introduced a new feature called property hooks. It’s exactly what it sounds like — it allows you to modify a property’s value with special hooks.

To understand how it works, it makes sense for us to look at how we would validate property values before PHP 8.4 with traditional getters and setters:

<?php

class Product
{
    private float $price;

    public function getPrice(): float
    {
        return $this->price;
    }

    public function setPrice(float $price): void
    {
        if ($price < 0) {
            throw new InvalidArgumentException('Price cannot be negative');
        }
        
        $this->price = $price;
    }
}

Let’s transform this code into a much more elegant version.

Rather than simply defining the property visibility on this line, we’ll open it up with some curly braces, and also change the visibility to public:

<?php

class Product
{
    public float $price {
        // We'll add our hooks here
    }
}

Even though the property is public, we can control the access to this property with hooks.

Let's start with the getter hook:

<?php

class Product
{
    public float $price {
        get {
            return $this->price;
        }
        
        // We could also use arrow syntax:
        // get => $this->price;
    }
}

The syntax for hooks look like functions. We don’t have any parameters here, so we can eliminate the parenthesis.

We could also use PHP’s arrow syntax to shorten this logic to a single line when we we simply return a value.

Now let’s look at our setter:

<?php

class Product
{
    public float $price {
        get => $this->price;
        set (float $value) {
            if ($value < 0) {
                throw new InvalidArgumentException('Price cannot be negative');
            }

            $this->price = $value;
        }
    }
}

The set hook syntax is similar to our getter, but it receives a value as a parameter. We can then define all of our business logic within this hook, just like our traditional setter.

Implementing property hooks also feels way more natural:

<?php

$product = new Product();

$product->price = 100;  // Works fine

echo $product->price;   // Outputs: 100

$product->price = -50;  // Throws error: Price cannot be negative

Notice how we're now working directly with the price property — rather than calling setPrice() or getPrice(), we can use the clean syntax of public properties, but without sacrificing the safety of getters and setters.

Pro tip: Property hooks work best for straightforward validation. For complex logic or when you need to work with multiple properties, traditional getters and setters might still be your best choice.