From a061dea67a9b90826a0f55b3a1ec05a8a8b1e229 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Sun, 3 May 2026 17:14:27 +0700 Subject: [PATCH 1/4] Optimize performance of `AbstractActiveRecord::get()` method --- src/AbstractActiveRecord.php | 13 +++++++++++-- src/ActiveRecord.php | 5 +++++ src/Trait/MagicPropertiesTrait.php | 9 +++++++++ src/Trait/PrivatePropertiesTrait.php | 5 +++++ 4 files changed, 30 insertions(+), 2 deletions(-) diff --git a/src/AbstractActiveRecord.php b/src/AbstractActiveRecord.php index 9be9d6a16..ec3a40b6b 100644 --- a/src/AbstractActiveRecord.php +++ b/src/AbstractActiveRecord.php @@ -92,7 +92,7 @@ public function equals(ActiveRecordInterface $record): bool public function get(string $propertyName): mixed { - return $this->propertyValuesInternal()[$propertyName] ?? null; + return $this->propertyValueInternal($propertyName); } public function propertyValues(?array $names = null, array $except = []): array @@ -763,10 +763,19 @@ public function db(): ConnectionInterface return ConnectionProvider::get(); } + /** + * Returns the value of a property for an Active Record object. + * + * @param string $name Property name + * + * @return mixed Property value or `null` if the property is not set. + */ + abstract protected function propertyValueInternal(string $name): mixed; + /** * Returns the available property values of an Active Record object. * - * @return array + * @return array The property values (name-value pairs). * * @psalm-return array */ diff --git a/src/ActiveRecord.php b/src/ActiveRecord.php index 410d1a5c8..44d8998d0 100644 --- a/src/ActiveRecord.php +++ b/src/ActiveRecord.php @@ -125,6 +125,11 @@ public function primaryKey(): array return $this->tableSchema()->getPrimaryKey(); } + protected function propertyValueInternal(string $name): mixed + { + return $this->$name ?? null; + } + protected function propertyValuesInternal(): array { return ArArrayHelper::propertyValues($this); diff --git a/src/Trait/MagicPropertiesTrait.php b/src/Trait/MagicPropertiesTrait.php index 3be39cb42..23c54431d 100644 --- a/src/Trait/MagicPropertiesTrait.php +++ b/src/Trait/MagicPropertiesTrait.php @@ -221,6 +221,15 @@ public function canSetProperty(string $name, bool $checkVars = true): bool || $this->hasProperty($name); } + protected function propertyValueInternal(string $name): mixed + { + if ($name !== 'propertyValues' && property_exists($this, $name)) { + return $this->$name ?? null; + } + + return $this->propertyValues[$name] ?? null; + } + /** @psalm-return array */ protected function propertyValuesInternal(): array { diff --git a/src/Trait/PrivatePropertiesTrait.php b/src/Trait/PrivatePropertiesTrait.php index fb60d3d9a..54a9c842b 100644 --- a/src/Trait/PrivatePropertiesTrait.php +++ b/src/Trait/PrivatePropertiesTrait.php @@ -17,6 +17,11 @@ */ trait PrivatePropertiesTrait { + protected function propertyValueInternal(string $name): mixed + { + return $this->$name ?? null; + } + protected function populateProperty(string $name, mixed $value): void { $this->$name = $value; From 89165f99c9c3c17e7610b8e01189a38ce1e8a77a Mon Sep 17 00:00:00 2001 From: Tigrov Date: Sun, 3 May 2026 17:24:16 +0700 Subject: [PATCH 2/4] Use `get()` method --- src/AbstractActiveRecord.php | 14 -------------- src/ActiveRecord.php | 10 +++++----- src/Trait/MagicPropertiesTrait.php | 18 +++++++++--------- src/Trait/PrivatePropertiesTrait.php | 4 ++-- 4 files changed, 16 insertions(+), 30 deletions(-) diff --git a/src/AbstractActiveRecord.php b/src/AbstractActiveRecord.php index ec3a40b6b..c1521bbd3 100644 --- a/src/AbstractActiveRecord.php +++ b/src/AbstractActiveRecord.php @@ -90,11 +90,6 @@ public function equals(ActiveRecordInterface $record): bool return $this->tableName() === $record->tableName() && $this->primaryKeyValues() === $record->primaryKeyValues(); } - public function get(string $propertyName): mixed - { - return $this->propertyValueInternal($propertyName); - } - public function propertyValues(?array $names = null, array $except = []): array { $names ??= $this->propertyNames(); @@ -763,15 +758,6 @@ public function db(): ConnectionInterface return ConnectionProvider::get(); } - /** - * Returns the value of a property for an Active Record object. - * - * @param string $name Property name - * - * @return mixed Property value or `null` if the property is not set. - */ - abstract protected function propertyValueInternal(string $name): mixed; - /** * Returns the available property values of an Active Record object. * diff --git a/src/ActiveRecord.php b/src/ActiveRecord.php index 44d8998d0..9ee4c107a 100644 --- a/src/ActiveRecord.php +++ b/src/ActiveRecord.php @@ -79,6 +79,11 @@ */ class ActiveRecord extends AbstractActiveRecord { + public function get(string $propertyName): mixed + { + return $this->$propertyName ?? null; + } + public function propertyNames(): array { return $this->tableSchema()->getColumnNames(); @@ -125,11 +130,6 @@ public function primaryKey(): array return $this->tableSchema()->getPrimaryKey(); } - protected function propertyValueInternal(string $name): mixed - { - return $this->$name ?? null; - } - protected function propertyValuesInternal(): array { return ArArrayHelper::propertyValues($this); diff --git a/src/Trait/MagicPropertiesTrait.php b/src/Trait/MagicPropertiesTrait.php index 23c54431d..b35346c28 100644 --- a/src/Trait/MagicPropertiesTrait.php +++ b/src/Trait/MagicPropertiesTrait.php @@ -165,6 +165,15 @@ public function hasRelationQuery(string $name): bool return method_exists($this, "get{$name}Query"); } + public function get(string $propertyName): mixed + { + if ($propertyName !== 'propertyValues' && property_exists($this, $propertyName)) { + return $this->$propertyName ?? null; + } + + return $this->propertyValues[$propertyName] ?? null; + } + public function set(string $propertyName, mixed $value): void { if ($this->hasProperty($propertyName)) { @@ -221,15 +230,6 @@ public function canSetProperty(string $name, bool $checkVars = true): bool || $this->hasProperty($name); } - protected function propertyValueInternal(string $name): mixed - { - if ($name !== 'propertyValues' && property_exists($this, $name)) { - return $this->$name ?? null; - } - - return $this->propertyValues[$name] ?? null; - } - /** @psalm-return array */ protected function propertyValuesInternal(): array { diff --git a/src/Trait/PrivatePropertiesTrait.php b/src/Trait/PrivatePropertiesTrait.php index 54a9c842b..c931decc5 100644 --- a/src/Trait/PrivatePropertiesTrait.php +++ b/src/Trait/PrivatePropertiesTrait.php @@ -17,9 +17,9 @@ */ trait PrivatePropertiesTrait { - protected function propertyValueInternal(string $name): mixed + public function get(string $propertyName): mixed { - return $this->$name ?? null; + return $this->$propertyName ?? null; } protected function populateProperty(string $name, mixed $value): void From 681a078d558cea56c7bbfaeecd14a98efd85a942 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Sun, 3 May 2026 17:28:46 +0700 Subject: [PATCH 3/4] Fix bc --- src/AbstractActiveRecord.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/AbstractActiveRecord.php b/src/AbstractActiveRecord.php index c1521bbd3..985f8d90c 100644 --- a/src/AbstractActiveRecord.php +++ b/src/AbstractActiveRecord.php @@ -90,6 +90,11 @@ public function equals(ActiveRecordInterface $record): bool return $this->tableName() === $record->tableName() && $this->primaryKeyValues() === $record->primaryKeyValues(); } + public function get(string $propertyName): mixed + { + return $this->propertyValuesInternal()[$propertyName] ?? null; + } + public function propertyValues(?array $names = null, array $except = []): array { $names ??= $this->propertyNames(); From 9c1d17897fdab214715894030571098f3dee31a1 Mon Sep 17 00:00:00 2001 From: Tigrov Date: Sun, 3 May 2026 18:02:05 +0700 Subject: [PATCH 4/4] Add line to CHANGELOG.md [skip ci] --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea1b1846b..036d4bc04 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ - Bug #562: Fix `ActiveRecordInterface::upsert()` to prioritize passed associative values during updates (@Tigrov) - Bug #561: Fix `ActiveRecordInterface::upsert()` with `$updateProperties = false` (@Tigrov) - Bug #550: Relation query should be created by related class, not primary model class (@batyrmastyr) +- Enh #571: Optimize performance of `ActiveRecord::get()` method (@Tigrov) ## 1.0.2 March 11, 2026