stanley-cheung/protobuf-php

Google的Protocol Buffers的PHP实现

v0.6 2016-07-22 02:12 UTC

This package is not auto-updated.

Last update: 2024-09-18 20:07:09 UTC


README

[更新 2016-02-08: Google官方protobuf实现从版本3.1.0+开始支持PHP。gRPC从v1.1.0+版本开始切换到使用该Proto3实现。这个分支将不再维护。]

PHP的Protobuf

PHP的Protobuf是Google的Protocol Buffers在PHP语言中的实现,支持其二进制数据序列化,包括一个protoc插件,可以从.proto文件生成PHP类。

在生成包含各种类型提示的PHP文件上投入了大量努力,以帮助IDE进行自动完成。因此,它不仅可以用于与Protocol Buffers服务通信,还可以用作生成最终序列化方式不定的数据对象的生成工具。

有关更多信息,请参阅包含的手册页

需求

  • PHP 5.3
  • Pear的Console_CommandLine(用于protoc包装工具)
  • Google的protoc编译器版本2.3或更高
  • GMP或BC Math扩展 ¹

¹ 只在int32int64fixed64类型的负值时需要。请参阅“已知问题”部分。

功能

正在运行

  • 标准类型(数字、字符串、枚举、消息等)
  • 可插拔的序列化后端(编解码器)
    • 标准二进制格式
    • 标准TextFormat ¹
    • PhpArray
    • JSON
    • ProtoJsonTagMapIndexed变体)
    • XML
  • Protoc编译器插件,用于生成PHP类
  • 扩展
  • 未知字段
  • 打包字段
  • 反射
  • 支持带注释的动态消息
  • 生成服务接口
  • 在生成的文件中包含.proto文件中的注释
  • 方便安装的Pear包

¹ 仅支持序列化

未来

  • 代码生成模式的速度优化
  • 支持超出PHP原生限制的数字

示例用法

<?php
require_once 'DrSlump/Protobuf.php';
\DrSlump\Protobuf::autoload();

$person = new Tutorial\Person();
$person->name = 'DrSlump';
$person->setId(12);

$book = new Tutorial\AddressBook();
$book->addPerson($person);

// Use default codec
$data = $book->serialize();

// Use custom codec
$codec = new \DrSlump\Protobuf\Codec\Binary();
$data = $codec->encode($book);
// ... or ...
$data = $book->serialize($codec);

安装

使用Pear安装

rake pear:package version=1.0
[sudo] pear install Protobuf-1.0.tgz

您也可以通过在计算机上检出仓库的副本来获取最新版本。

已知问题

类型

PHP在处理数字方面非常弱。已应用了几种解决方案,以减少Protobuf类型和PHP类型之间的不兼容性。

  • Protobuf使用IEEE 754标准存储浮点值,对于double类型使用64位字,对于float类型使用32位字。PHP原生支持IEEE 754,尽管精度取决于平台,但通常支持64位双精度浮点数。这意味着如果您的PHP是用64位大小的双精度浮点数(或更大)编译的,那么您应该没有问题用Protobuf编码和解码浮点型和双精度型值。

  • 在PHP中,整数值也是平台相关的。该库是在针对使用64位整数编译的PHP二进制文件开发的。编码和解码算法理论上应该适用于PHP内部使用32位或64位整数的情况,只需注意,使用32位整数时,数字不能超过任何情况下的PHP_INT_MAX值(2147483647)。

    虽然Protobuf支持无符号整数,但PHP不支持。事实上,超过编译后的PHP最大整数(PHP_INT_MAX,64位为0x7FFFFFFFFFFFFFFF)的数字将被自动转换为双精度浮点数,这通常提供53位的十进制精度,允许安全地处理高达0x20000000000000(2^53)的数字,即使它们在PHP中以浮点数的形式表示而不是整数。更高的数字会丢失精度,甚至可能返回一个无穷大值,请注意,库不包含对这些数字的任何检查,使用它们可能会引发意外的行为。

    当以int32int64fixed64类型编码时,负值需要PHP环境中可用的大整数扩展GMPBC Math(后者仅适用于64位架构)。原因是,当没有使用zigzag来编码这些负数时,二进制表示使用最高位作为符号位,因此这些数字变得高于PHP支持的最大值。库将检查这些条件,并自动尝试使用GMP或BC来处理值。

字符串

二进制编解码器期望字符串使用UTF-8编码。PHP原生不支持字符串编码,PHP的字符串数据类型基本上是一个长度限定的字节流,因此将自动编码转换包括到库的编码和解码例程中并不简单。而不是尝试猜测或提供配置界面以进行编码,二进制编解码器将像处理byte类型一样处理string类型,将编码或解码任务委托给您的应用程序。

内存使用

由于库的建模方式不允许将消息作为流进行解析或序列化,大型消息可能会很麻烦。整个操作都在内存中执行,这允许更快的处理,但如果消息太大,可能会消耗太多RAM。

未知字段

由于不同编解码器的格式中的wire类型不同,因此无法将一个编解码器中消耗的未知字段转换为另一个编解码器。这意味着,例如,当使用二进制编解码器消耗消息时,如果其中包含未知字段,它们在使用Json编解码器序列化消息时将不会被包含。

生成PHP类

生成工具设计为作为protoc插件运行,因此它应该与官方编译器支持的任何proto文件一起工作。

protoc --plugin=protoc-gen-php --php_out=./build tutorial.proto

要使用proto文件中的非标准选项(如php.namespace),您必须导入随库提供的php.proto文件。它的位置将取决于您安装此库的位置。

protoc -I=./Protobuf-PHP/library/DrSlump/Protobuf/Compiler/protos \
       --plugin=protoc-gen-php --php_out=./build tutorial.proto

为了使您的生活更轻松,提供的protoc插件提供了一个额外的执行模式,其中它作为protoc调用的包装器。它将自动包含php.proto路径,这样您就无需担心它。

protoc-gen-php -o ./build tutorial.proto

许可协议

The MIT License

Copyright (c) 2011 Iván -DrSlump- Montes

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.