PHP协议缓冲区与高效序列化 PHP协议缓冲区与高效序列化序列化是数据交换的基础。PHP的serialize和JSON是最常用的序列化格式但性能不是最优的。协议缓冲区Protocol Buffers是一种更高效的序列化格式。今天说说PHP中的序列化方案选择。先对比各种序列化方案的性能。phpclass SerializationBenchmark{private array $data;public function __construct(){$this-data $this-generateTestData();}private function generateTestData(): array{$data [];for ($i 0; $i 1000; $i) {$data[] [id $i,name User_{$i},email user{$i}example.com,age rand(18, 80),tags [php, developer, backend],scores [math rand(60, 100),english rand(60, 100),],];}return $data;}public function benchmarkSerialize(string $name, callable $serialize, callable $unserialize): array{$start microtime(true);$serialized $serialize($this-data);$serializeTime (microtime(true) - $start) * 1000;$start microtime(true);$unserialized $unserialize($serialized);$unserializeTime (microtime(true) - $start) * 1000;return [format $name,serialized_size strlen($serialized),serialize_time_ms round($serializeTime, 3),unserialize_time_ms round($unserializeTime, 3),matches $unserialized $this-data ? 一致 : 不一致,];}public function run(): void{$results [];$results[] $this-benchmarkSerialize(PHP序列化,fn($d) serialize($d),fn($d) unserialize($d));$results[] $this-benchmarkSerialize(JSON,fn($d) json_encode($d, JSON_UNESCAPED_UNICODE),fn($d) json_decode($d, true));$results[] $this-benchmarkSerialize(JSON(压缩),fn($d) json_encode($d),fn($d) json_decode($d, true));$results[] $this-benchmarkSerialize(MsgPack,fn($d) msgpack_pack($d),fn($d) msgpack_unpack($d));echo str_pad(格式, 18) . str_pad(大小(bytes), 15) . str_pad(序列化(ms), 15) . str_pad(反序列化(ms), 15) . \n;echo str_repeat(-, 63) . \n;foreach ($results as $r) {if ($r null) continue;echo str_pad($r[format], 18). str_pad($r[serialized_size], 15). str_pad($r[serialize_time_ms], 15). str_pad($r[unserialize_time_ms], 15) . \n;}}}if (extension_loaded(msgpack)) {$bench new SerializationBenchmark();$bench-run();} else {echo MsgPack扩展未安装\n;}?高效的二进制序列化方案对比phpclass BinarySerializer{// 自制二进制序列化public static function pack(array $data): string{$binary pack(n, count($data));foreach ($data as $item) {$name $item[name] ?? ;$email $item[email] ?? ;$age $item[age] ?? 0;$binary . pack(n, strlen($name)) . $name;$binary . pack(n, strlen($email)) . $email;$binary . pack(C, $age);}return $binary;}public static function unpack(string $binary): array{$offset 0;$count unpack(n, substr($binary, $offset, 2))[1];$offset 2;$result [];for ($i 0; $i $count; $i) {$nameLen unpack(n, substr($binary, $offset, 2))[1];$offset 2;$name substr($binary, $offset, $nameLen);$offset $nameLen;$emailLen unpack(n, substr($binary, $offset, 2))[1];$offset 2;$email substr($binary, $offset, $emailLen);$offset $emailLen;$age unpack(C, substr($binary, $offset, 1))[1];$offset 1;$result[] compact(name, email, age);}return $result;}}$data [[name 张三, email zhangsantest.com, age 28],[name 李四, email lisitest.com, age 35],];$packed BinarySerializer::pack($data);echo 二进制序列化长度: . strlen($packed) . 字节\n;$unpacked BinarySerializer::unpack($packed);print_r($unpacked);?序列化方案的选择取决于具体需求。JSON是最通用的格式跨语言支持最好。PHP序列化可以保留对象类型但不跨语言。Protocol Buffers性能最好、数据最小但需要定义Schema。MsgPack是JSON的二进制替代性能和大小介于JSON和Protobuf之间。在性能敏感的RPC场景中Protocol Buffers是首选。