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:

  1. It only checks references for objects.
  2. It converts Serializable objects to strings when the target version is PHP4.
  3. It has a setting that allows you to automatically convert any object to an array or STDClass.
  4. It ignores all private and protected variables.

Web mentions

Comments

  • Sebastian Bergmann

    Sebastian Bergmann

    What about spl_object_hash() (http://php.net/spl_object_hash)?
  • Lukas

    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

    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

    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

    Bruce Weirdan

    To get private/protected properties you could parse the var_export($obj, true) output
  • Evert

    Evert

    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

    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 anymore
  • Bruce Weirdan

    Bruce Weirdan

    Watch for recursion though. I don't know how I would detect it if I was parsing object's plain text representation
  • Evert Pot

    Evert 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

    mod rewrite

    Don't use php4.