Grigory Ilizirov
Grigory Ilizirov

Reputation: 1028

Is there a simple PHP way to minimize the class name in serialization?

I have a group of objects I need to serialize, but the class names are long, for example:

"\Namespace1\Subnamespace\dataobjectA"  
"\Namespace1\Subnamespace\dataobjectB"  
"\Namespace1\Subnamespace\dataobjectC"  
"\Namespace1\Subnamespace\dataobjectD"

using the serialize function on the objects, I get: "O:41:\"Namespace1\Subnamespace\dataobjectC\":1:{s:4:"data";s:9:"some data";}"

the serialization string contains the full class name which is sometimes bigger than the data :)

My question is: Is there a simple PHP way to minimize the class name in serialization

Any suggestion are welcome

Upvotes: 3

Views: 1712

Answers (2)

Conor Mancone
Conor Mancone

Reputation: 2030

I have a good answer, a bad answer, and then an answer that addresses your question.

Good Answer

If I can take this somewhere else entirely: you probably don't really want to do this at all. You mention that the class names are sometimes longer than the actual data. If that is the case, then overall you have almost no data in your serialization. Unless you have some ridiculously long namespaces/class names (in which case you might want to reconsider your application structure), I imagine your serialized strings will very easily fit into, for instance, a MySQL text field. The point is, if you only have a little bit of data, I really doubt it is worth the effort to muck with a standard format to trim off what amounts to less than a kilobyte of data. Any reasonable database and server will be be able to handle these things without trouble, even if you have millions and millions of such records. So unless this is some kind of low-memory embedded device, I would be curious to hear why you think you need to do this (of course that is rhetorical: I seriously doubt you are running PHP on an embedded device).

If you do try to do something like this, you're going to add code that you are going to have to maintain that everyone will look at after you and say "what in the world is going on here?". It does depend on your need, but I'm suspicious that you are more likely to introduce problems via the code that will make this feature happen, than you will by simply letting your serialized data be long.

Bad Answer

I really don't think you want to make any changes to the serialized data. To answer one of your questions directly: no, there is no way to shorten the namespace and still use the unserialize() method of PHP, except by ditching namespaces altogether in your application. I really doubt you want to do that.

Your other option is to manually adjust the serialized string yourself. You could then store this "modified serialized format" (let's call it modSerialized). Then, when you need to unserialize, you have to reverse your modSerialized function and can run unserialize() normally. The trouble with this is that the output of PHP's serialize method represents a standard and well-established encoding. Modifying it is going to be inherently error-prone and, by definition, will go against standard best-practices. You can do this without errors if you are very careful and write lots of code, which again, I don't think you want to do. For instance you could imagine finding and replacing \Namespace1\Subnamespace\dataobjectA with gibberish, because you want to make sure you don't accidentally replace it with something that is actually found in your string. You then have to remember what gibberish you put in, and what it represents, so you can reverse it later. If you manage to do that successfully, then good new! You just re-invented the wheel and have an ad-hoc compression algorithm built!

So really, you don't want to do that either. Or if you do, just take the answer @Blackbam gave and compress your data with a normal compression algorithm. That would be less weird.

Another option

Finally, if you don't like any of the above suggestions, then there is one more: ditch the PHP serialize() all together. Obviously it is not a good fit for your needs. As a result, it is better to come up with a solution that is a good fit for your needs then to try to modify a well-established standard to fit your problem. Going down that route will give you a chimera that doesn't work for anyone.

What would this look like? It depends on your problem. For instance, you could establish some abbreviations for the class names in your system. Then when it comes time to serialize you could make an array that contains the abbreviated class name, and a string representation of the objects data that needs to be persisted so that it can be rebuilt. Then find some encoding for that: it could just be JSON, or even php serialize, or some other format. Then, manually build your own unserialize() method to reconstruct the object from your own serialization representation. Basically, make your own serialize() and unserialize().

Upvotes: 3

Blackbam
Blackbam

Reputation: 19386

If you are worried about the length of your data you may compress it with some good compression function.

This is a working example:

class Tester {
    public $name;
    public $age;
}

$a = new Tester();

$a->name = "Harald the old Capttttttttttttain               is going to live very long.";
$a->age = 999999999;

$ser = serialize($a);
var_dump($ser);

$comp = gzcompress($ser,9);

var_dump($comp);

Result:

string(133) "O:6:"Tester":2:{s:4:"name";s:75:"Harald the old Capttttttttttttain is going to live very long.";s:3:"age";i:999999999;}"

string(108) "x��2�R I-.I-R�2��.�2�R�K�MU�.�27�R�H,J�IQ(�HU��Ή%H 13Od+��g�+��+�d����U���끌4�RJL�ie ֵ�Һ(�"

Of course the latter is not human readable anymore and will be useless in database searches but it is way shorter.

There are different compression mechanisms for PHP bzcompress (http://php.net/manual/en/function.bzcompress.php) may be better than gzcompress.

Upvotes: 4

Related Questions