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
Serializing a Collection results in error when unserializing and manipulating it #6228
Comments
What code triggered this error? |
I think implementing |
|
would you say there's not anything inherently incompatible with serializing a Collection? I'm not too keen on this, but for example I understand there's currently no way of serializing a closure. Most collections I use have a bunch of them :) |
The main problem of serializing collections is deciding whether you want to serialize with array keys or without them, but in general all collections can be serialized if they are rewindable. I can guide you to implement this feature if you like |
sure, wouldn't know where to start though :) |
Yes, the main pattern used to implement collections is Decorator. Start by adding and implementing this interface in the Collection object http://php.net/manual/en/class.serializable.php |
that's the easy part :) |
@lorenzo Couldn't you also process the collection into a static set of data and serialize the results of that? Similar to serializing the results of toArray()? |
That is the idea that I have in mind, but using to array will not be enough. It needs to eb an object having items stored in this way: [
[key1, value1],
[key2, value2],
[key3, value3],
...
] So when unserialized, the person can choose whether to use |
@markstory what do you mean by that? Here's my (little) understanding of the whole Collection impl + SPL iterators: A Collection begins with an initial Array or Traversable object. Then when you start manipulating the collection each method wraps the previous Iterator adding each manipulation. Nothing is executed until iterated or the toArray or compile method is called. When called, and this is the part I understand the less, the _unwrap method does something I cant fully understand, but what usually happens is that each item in the Traversable object starts going up the layers of transformations (some get filtered in the way) until a final Collection is returned or some computed value. Ir order to to this, usually Closures are involved, and since most Collection methods accept callables, class or instance methods could be involved, or global functions, etc. Now, how on earth do we serialize that? :| sorry, I'm trying to help, but also trying to learn and deeply understand this |
Hehe, don't worry. So to make the task more specific, this is the outline of what needs to be done:
This class implements So for each call to
In particular, for each element the method
It will take the internal array and serialize it:
$multi = new MultiKeysIterator();
foreach ($this as $key => $element) {
$multi->add($key, $element);
}
return serialize($multi);
$unserialized = unserialize($serializedString);
return new Collection(new MultiKeysIterator($unserialized)); |
heh, you sound very confident! perfect, I'll do it |
can you help me understand the reasoning behind all this? :) |
Simply calling toArray() won't work as the unserialized result could have toList() called on it, and the results would not match the pre-serialized object. Also because of how iterators work, keys can be duplicated which is why @lorenzo is recommending the data be stored as |
@ramiroaraujo Actually, I just remember where this implementation idea came from... It is already implemented!! So, no need to implement that again. We just need to implement |
great! :D |
@lorenzo I've been trying out, but hit a few dead ends.
as an extra, the Serializable interface dictates that the unserialize method should not return anything... woooooooow? |
would it be easier for you to implement |
I'm closing this since the way of caching database results is working correctly. We have decided to not implement the Serializable interface for collections as it makes the code much more difficult to sue and understand. |
I found this while caching some database results, that ended up wrapped in a Collection. When serializing the collection compile returns, the unserialized Collection would return
PHP Fatal error: Uncaught exception 'LogicException' with message 'The object is in an invalid state as the parent constructor was not called' in ...
when trying to perform any operation on it.If the case is that any collection will fail if reconstructed from a serialization, then we should document that and throw an Exception when trying to serialize, but I'm not sure that's the case, and I'm not familiar with the internals of Colleciton and it's friends.
Happy to implement and document this, but would like to be sure first :)
The text was updated successfully, but these errors were encountered: