Property hooks from PHP 8.4
As PHP 8.4 comes with property hooks we could remove virtual properties, as they would be completely modelled by a custom property with getter hook.
This:
/** ...
* @property-read int $age {virtual}
*/
final class Author extends Entity
{
protected function getterAge(): int
{
if ($this->born === null) {
return 0;
}
return ((int) date('Y')) - ((int) $this->born->format('Y'));
}
}
Would become
/** ...
*/
final class Author extends Entity
{
public int $age {
get {
if ($this->born === null) {
return 0;
}
return ((int) date('Y')) - ((int) $this->born->format('Y'));
}
}
}
Please note, that this would not mean removing custom getters/setters support, as they're still needed for non-virtual properties.
I have an use case where I fetch "extended" entity with properties that are not available in original table. Something like:
/**
* ...
* @property-read DateTimeImmutable $changedAt
*/
class JoinedEntity extends Entity {}
Where value for $changedAt comes from joined table:
SELECT
pt.*,
l.changed_at
FROM primary_table pt
LEFT JOIN (SELECT l.change_at FROM ... )
When given entity is being persisted, these extended properties are marked as virtual to avoid ORM attempting to persist them. After persisting they are reset.
// Required for correct behavior on persisting values not present in mapper DB table
public function onBeforeInsert(): void
{
parent::onBeforeInsert();
$this->metadata->getProperty('changedAt')->isVirtual = true;
$this->metadata->getProperty('changedBy')->isVirtual = true;
}
public function onAfterInsert(): void
{
parent::onAfterInsert();
$this->metadata->getProperty('changedAt')->isVirtual = false;
$this->metadata->getProperty('changedBy')->isVirtual = false;
}
I don't remember exactly why it was implemented this way, but it was the only solution we came with.