[9.x] Traversable should have priority over JsonSerializable in EnumerateValues #44456
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Using an unrelated third party package I came across this problem, this exact same issue happened to someone else, as per (laravel/ideas#2556) and was introduced in #14628.
Problem
EnumerateValues::getArrayableItems checks for JsonSerializable before checking for Traversable.
This is a problem because a class implementing both JsonSerializable and Traversable will have its JSON representation used in the Collection instead of its actual iterable representantion, which should have priority. There is no need to transform a Traversable object to a JSON.
This is not an expected behaviour since a Traversable object can be traversed (no pun intended).
Consider the following:
EnumerateValues::getArrayableItems will use MyIterator JSON representantion, and now the items in the Collection will no longer be of type Person, meaning that $collection->first()->getFullName() will throw
Call to a member function getFullName() on array
.That's assumming that the implementation of jsonSerialize returns an array of the items, but it can be worse if it returns other data such as:
Although this can be solved in user-land, EnumerateValues should accurately parse the items given the fact that Traversable is a native PHP feature.