-
Notifications
You must be signed in to change notification settings - Fork 11.4k
[9.x] Loose comparison causes the value not to be saved #41337
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…f the castable type object/collection.
Personally, I stand with PHP on this, and think a change in order means that the value is no longer the same and should be updated. Implementing it as is, the worst-case scenario would be an extra If the order thing is a big deal, it would be possible to add a recursive |
I agree that the current situation seems a little worse than the change in behavior introduced by this PR. Will think about it over the weekend. |
I've also met with this problem. Could it be a solution to use Arr::dot($this->fromJson($attribute)) == Arr::dot($this->fromJson($original)); |
$attribute = [
'b' => [
'c' => 1
]
];
$original = [
'b' => [
'c' => true
]
];
Arr::dot($attribute) == Arr::dot($original); // Returns true, should be false. Since loose comparison is the cause of the problem |
I see. Another solution that crossed my mind: $a = Arr::dot($this->fromJson($attribute));
$o = Arr::dot($this->fromJson($original));
count($a) === count($o) && empty(array_diff_assoc($a, $o)); Note, comparing the count of the array elements is necessary, because let's say if What do you think about that solution? Okay, I see what do you mean. This solution won't work because |
Yup, same for all other "loose" vs "strict" comparisons differences https://www.php.net/manual/en/types.comparisons.php |
Can this be fixed by retrieving the items as an array, using |
Yes that would be possible (when using recursive |
May be this will need a flag or sort in the Model: protected $strictComparison = ['my-array']. This way users can opt-in when dealing with comparing model attributes. |
This PR breaks BC. If original $value is |
The issue has been addressed in #37961.
Given an attribute with the cast
object
orcollection
, the$model->isDirty()
method returns the wrong value due to the use of loose comparison.Example from issue #37961:
The solution proposed by @krnsptr link is in my opinion the best solution.
Furthermore, casting the attributes to object/collection prior to checking the values, makes no sense to me. We are interested in knowing if the content differs, the cast prior to this check does not provide useful additional information (only causes that you can't use strict comparison due to object being always different even with the same content). The cast also adds overhead.