PHP serializer in userland code
I did a bit of work on an alternative for serialize(), written in PHP.
I wanted to build this as a helper class for a draft-PHP-RPC server. The reason I needed a custom one was because I wanted to make sure I would be able to spit out PHP4-compatible serialized data, and in the future, when its ported to PHP6, also PHP5-compatible data.
Some of my findings:
- Its dead-slow, compared to the built-in version (as expected). What PHP's built in serializer could do in 0.00366 seconds, I needed 0.0948.
- So even though its CPU expensive, there is less memory needed for big structures, because it uses echo so it can stream it straight to the client if needed.
- When a property is private or protected, it really is. There's no way to grab the value. I was hoping Reflection would have allowed me to cheat.
- There's no proper way to find out if two variables reference the same data. The only way is to change one of them, and see if the second also changed.
- I was hoping SPLObjectStorage would be able to give me back an index the stored object. Instead I'm looping through all the objects I got and use === to see if they are the same.
I'm starting to wonder now if its a better idea to just use serialize() and make the needed fixes with regexes and stuff, but thats an experiment for an other night.
For the people who might find it useful, here's the download and source code..
List of differences with PHP's serialize:
- It only checks references for objects.
- It converts Serializable objects to strings when the target version is PHP4.
- It has a setting that allows you to automatically convert any object to an array or STDClass.
- It ignores all private and protected variables.
Comments
Sebastian Bergmann •
What about spl_object_hash() (http://php.net/spl_object_hash)?Lukas •
Hi,You may also consider using json alternatively. In this context you might find my recent benchmarks useful:
http://pooteeweet.org/blog/721
regards,
Lukas
Jelmer •
"I was hoping Reflection would have allowed me to cheat."It does, doesn't it? I tried a bit, and for me, this is working:
This code, a class containing private properties wich can be read using ReflectionProperty. It echo's '255', as I expected.
Evert •
Sebastian,spl_object_hash is a great idea!
Lukas,
JSON is not really an option as I'm really looking for a RPC-scheme between PHP servers, supporting class mapping.
Jelmer,
I don't know which PHP version you are running, but PHP 5.2 and upwards doesn't support it. It might have worked in older versions, but as of right now, I don't have a way to verify that.
(by the way, I miss chocomel.. Haven't had that for so long and there's no way I can get it here!)
Bruce Weirdan •
To get private/protected properties you could parse the var_export($obj, true) outputEvert •
Thats smart.. worth looking into. I didn't know it included private properties..Pretty ugly with the __set_state business though :) but its possible for sure.
Evert •
hm and in that case .. print_r or var_dump would also work .. If I used var_dump I don't think I'll need reflection at all anymoreBruce Weirdan •
Watch for recursion though. I don't know how I would detect it if I was parsing object's plain text representationEvert Pot •
currently my library doesn't check for recursion in arrays.. probably will prevent this problem with a nesting-depth check.I'm thinking now I should probably not go for parsing the var_dump/export/print_r output.. It makes more sense to simple parse the serialize() output, which is easier to do..
Which brings me back to my original idea.. to just do some regexes on the serialize() output to make the compatibility fixes..
mod rewrite •
Don't use php4.