是否有一种简单的PHP方法来最小化序列化中的类名?

时间:2017-07-25 16:32:02

标签: php serialization

我有一组需要序列化的对象,但类名很长,例如:

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

在对象上使用serialize函数,我得到: " O:41:\" Namespace1 \ Subnamespace \ dataobjectC \":1:{s:4:" data&#34 ;; s:9:"一些数据& #34 ;;}"

序列化字符串包含完整的类名,有时候大于数据:)

  • 我已经熟悉__sleep() ans __wakeup()函数,这里没用。

  • 我知道查找表的某些王需要

我的问题是: 是否有一种简单的PHP方法来最小化序列化中的类名

欢迎任何建议

2 个答案:

答案 0 :(得分:4)

如果您担心数据的长度,可以使用一些良好的压缩功能对其进行压缩。

这是一个有效的例子:

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);

结果:

  

string(133)“O:6:”Tester“:2:{s:4:”name“; s:75:”Harald the old   Capttttttttttttain将会活得很好   很长。“; s:3:”年龄“; i:999999999;}”

     

string(108)“x 2 R   I-.I-R2.2RKMU.27RH,JIQ(HUΉ%H   13Od + g + + d U 4 RJL ieֵ Һ( “

当然后者不再是人类可读的,在数据​​库搜索中没用,但它更短。

PHP bzcompress(http://php.net/manual/en/function.bzcompress.php)有不同的压缩机制可能比gzcompress更好。

答案 1 :(得分:2)

我有一个很好的答案,一个错误的答案,然后是一个解决你的问题的答案。

好答案

如果我可以完全把它带到其他地方:你可能根本就不想这样做。你提到类名有时比实际数据长。如果是这种情况,那么整体而言,序列化中几乎没有数据。除非你有一些非常长的命名空间/类名(在这种情况下你可能想重新考虑你的应用程序结构),我想你的序列化字符串很容易适合,例如,MySQL文本字段。关键是,如果你只有一些数据,我真的怀疑用标准格式来减少数量小于一千字节的数据是值得的。任何合理的数据库和服务器都能够毫无困难地处理这些事情,即使您拥有数以百万计的此类记录。因此,除非这是一种低内存的嵌入式设备,否则我很想知道为什么你认为你需要这样做(当然这是修辞的:我严重怀疑你是在嵌入式设备上运行PHP)。

如果你尝试做这样的事情,你将会添加你必须维护的代码,每个人都会看到你并且说“世界上有什么是继续在这儿?“它确实取决于您的需求,但我怀疑您更有可能通过代码实现此功能,而不是简单地让您的序列化数据很长。

错误答案

我真的不认为您想对序列化数据进行任何更改。直接回答你的一个问题:不,没有办法缩短命名空间并仍然使用PHP的unserialize()方法,除非在你的应用程序中完全抛弃名称空间。我真的怀疑你想这样做。

您的另一个选择是自己手动调整序列化字符串。然后,您可以存储此“已修改的序列化格式”(让我们称之为modSerialized)。然后,当您需要反序列化时,您必须反转modSerialized函数并正常运行unserialize()。这样做的问题在于PHP的serialize方法的输出代表了标准且完善的编码。修改它本身就容易出错,根据定义,它将违背标准的最佳实践。如果您非常小心并且编写了大量代码,那么您可以毫无错误地执行此操作,这也是我认为您不想做的事情。例如,您可以想象使用乱码来查找和替换\Namespace1\Subnamespace\dataobjectA,因为您要确保不会意外地将其替换为字符串中实际存在的内容。然后你必须记住你输入的是什么,以及它代表什么,所以你可以在以后改变它。如果你成功地做到了,那就好了!你刚刚重新发明了这个轮子,并建立了一个特殊的压缩算法!

所以,你真的不想这样做。或者,如果你这样做,只需接受@Blackbam给出的答案并使用正常的压缩算法压缩数据。那不会那么奇怪。

另一个选项

最后,如果您不喜欢上述任何建议,那么还有一个建议:将PHP serialize()放在一起。显然它不适合您的需求。因此,最好提出一个非常适合您需求的解决方案,然后尝试修改完善的标准以适应您的问题。沿着那条路走下去会给你一个对任何人都不起作用的幻想。

这会是什么样的?这取决于你的问题。例如,您可以为系统中的类名建立一些缩写。然后,当需要序列化时,您可以创建一个包含缩写类名的数组,以及需要持久化的对象数据的字符串表示,以便可以重建它。然后找到一些编码:它可能只是JSON,甚至PHP序列化,或其他一些格式。然后,手动构建自己的unserialize()方法,从您自己的序列化表示中重建对象。基本上,自己制作serialize()unserialize()