Skip to content

NotifyProperty::propertyChanged() and PHP 7.4+ type-hinted properties #13

@Deuchnord

Description

@Deuchnord

Since its version 7.4, PHP allows adding type hints to class properties. This is very useful to ensure the properties have the value type they are supposed to, but in some cases, they break the compatibility with the propertyChanged() method introduced by NotifyProperty trait.

For instance, let's say we have the following User class:

namespace App\Entity;

use CCMBenchmark\Ting\Entity\NotifyProperty;
use CCMBenchmark\Ting\Entity\NotifyPropertyInterface;

class User implements NotifyPropertyInterface
{
    use NotifyProperty;

    private int $id;
    private string $username;

    public function getId(): int
    {
        return $this->id;
    }

    public function getUsername(): string
    {
        return $this->username;
    }

    public function setUsername(string $username): string
    {
        $this->propertyChanged('username', $this->username, $username);
        return $this->username;
    }
}

The setUsername() calls the propertyChanged() from the trait to inform the ORM that we will want to update the username.
But this becomes a problem when the User is actually created from a denormalization with Symfony's Serializer component, because in this case, the normalizer will try to call setUsername() and fail with the following error:

Typed property App\Entity\User::$username must not be accessed before initialization

which is logic, because at this moment, the username property is not initialized yet, and we need it to call propertyChanged().

Of course, we could set the property nullable and initialize it to null, but this solution would lead to error-prone situations, where the value could be intentionally set to null and lead to errors on UODATE SQL queries, so this is not an ideal solution.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions