Uh oh!
There was an error while loading. Please reload this page.
refactor: Rework Entity class - #9878
Conversation
neznaika0
left a comment
There was a problem hiding this comment.
An actual note? We can already have the 'attributes' field
Uh oh!
There was an error while loading. Please reload this page.
michalsn
left a comment
There was a problem hiding this comment.
Some initial comments added.
If you fix a bug, it should be mentioned in the changelog as well.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
neznaika0
commented
Jan 9, 2026
I've lost the changes. I'll fix it |
6efe618 to
027a0f2CompareUh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
neznaika0
commented
Jan 11, 2026
|
neznaika0
commented
Jan 11, 2026
Additionally:
publicfunction__construct(array$data = [])
{
// ...$this->syncOriginal()->fill($data);
}
publicfunctionfill(array$data)
{
// ...
} |
michalsn
left a comment
There was a problem hiding this comment.
- The question remains refactor: Rework
Entityclass #9878 (review)
I think we could already with _setAttributes(). Since we dropped setAttributes(), I see no problem with removing this note.
I would return the array check and fix fill() -null is never needed there.
Users are allowed to create the Entity and fill it later. This change could break people's apps.
Uh oh!
There was an error while loading. Please reload this page.
neznaika0
commented
Jan 11, 2026
How? Does the default constructor have an empty array, and |
michalsn
commented
Jan 11, 2026
This is a BC break, which has no real benefit. |
neznaika0
commented
Jan 11, 2026
Good. Let's leave it. But we're breaking in 4.7. In my opinion, using null is the wrong developer code. php8.5 has already been released, and we still support the old standards. Of course, this is a concern for the developers... |
michalsn
commented
Jan 11, 2026
We do allow BC breaks, but only when they provide clear value or affect minimally exposed internals. This change does neither and would introduce unnecessary risk for users. That said, I'm not stubborn... if other maintainers think that this is the right direction, then I won't be opposed. |
michalsn
left a comment
There was a problem hiding this comment.
Other than this, looks good to me. Thanks.
Uh oh!
There was an error while loading. Please reload this page.
michalsn
left a comment
There was a problem hiding this comment.
Final round from me, cleanup only.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
I have another suggestion:
I haven't fully checked the tests, these are my thoughts... publicfunctiontestCIDatamap(): void
{
$entity = newclass () extends Entity
{
protected$attributes = [
'id' => null,
'full_name' => null, // In the $attributes, the key is the db column name'email' => null,
];
protected$datamap = [
// property_name => db_column_name'name' => 'full_name',
];
// For __get() similar checkspublicfunction__set(string$key, $value = null)
{
$dbColumn = $this->mapProperty($key);
// feat 2if (! $this->hasAttribute($dbColumn)) {
thrownewDomainException(
sprintf('Entity: The attribute "%s" was not found.', esc($dbColumn))
);
}
// feat 1$mappedProperty = $key === $dbColumn ? array_search($key, $this->datamap, true) : false;
if ($mappedProperty !== false) {
thrownewDomainException(
sprintf('Entity: Access to the "%s" property is possible via "%s".', esc($dbColumn), esc($key))
);
}
parent::__set($key, $value);
}
};
// Set via DB field// Now it work, after that it should cause an error (1)$entity->full_name = 'Ivan S.';
// Set via property class// It works in both cases$entity->name = 'Petr М.';
$entity->email = 'petr@mail.loc';
// Now it work, after that it should cause an error (2)$entity->undefined = 'Some string.';
} |
michalsn
commented
Jan 12, 2026
I don't think this qualifies as refactoring. While the change itself may be reasonable, it introduces a significant BC break.
|
It is more difficult to discuss on the forum, but there are no discussions in the repository. We have slack, but it's not available to me. I'm sorry to write here. You're right, this is a "feature request". The methods for DB are not affected at first glance: $entity = newclass ([]) extends Entity {
protected$attributes = [
'name' => null,
'role' => 'user',
'active' => true,
'profile' => null,
];
protected$datamap = [
'Name' => 'name',
'Role' => 'role',
'Active' => 'active',
];
};
$profile = new \stdClass();
$profile->city = 'Moscow';
// Access via field names from the DB, errors// $entity->name = 'Ivan';// $entity->role = 'admin';// $entity->active = false;$entity->Name = 'Ivan';
$entity->Role = 'admin';
$entity->Active = false;
$entity->profile = $profile;
self::assertSame(
[
'profile' => $profile,
'Name' => 'Ivan',
'Role' => 'admin',
'Active' => false,
],
$entity->toArray()
);
self::assertSame(
[
'name' => 'Ivan',
'role' => 'admin',
'active' => false,
'profile' => $profile,
],
$entity->toRawArray()
);
self::assertTrue($entity->hasChanged()); |
michalsn
commented
Jan 12, 2026
Fair enough, but as I mentioned, that's only half of the problem. While this would be a nice feature, BC is a priority in this case. |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
michalsn
commented
Jan 17, 2026
Thank you @neznaika0 |
Description
I keep track of entity changes. At the moment, I don't see any conflicts when using 'attributes' as the column name.
There was also a bug with the restore of
$_cast.Question: Do I need to get rid of the DataCaster object? For example, I completely disabled casting in the Entity and transform it into a Model. But the object is always being created.
I could, under the condition
$_cast = false, not create it or destroy it when calling$this->cast(false). We can simplify by callinggetDataCaster()"on the fly", although it's no better to create an object every time. Suggestions?It is also planned to update the DateCast to use the interface, since it does not always set DateTime, but also DateTimeImmutable.
PR should be taken after #9877 But we can discuss it now.Checklist: