2017/05/27

google-protobuf-php搭建


下载google-protobuf https://github.com/google/protobuf/releases

protobuf-php-3.2.0.tar.gz

解压进入目录编译生成protoc

tar zxvf protobuf-php-3.2.0.tar.gz
cd protobuf-3.2.0
./configure
make
make install

不使用源码安装,否则后面composer运行将失败,会提示

PHP Fatal error:  Cannot redeclare class Google\Protobuf\Internal\Descriptor in /mnt/work/demo/monolog/vendor/google/protobuf/php/src/Google/Protobuf/descriptor.php on line 96

新建一个测试目录demo,然后编写composer.json

{
    "name": "yangxg/demo",
    "description": "google protobuf php demo",
    "version": "1.0.0",
    "require": {
        "php": ">=5.5.0",
        "google/protobuf": "v3.*"
    },
    "autoload": {
        "psr-4":{
          "GPBMetadata\\": "proto/gen/GPBMetadata/",
          "Protodata\\": "proto/gen/Protodata/"
        }
    },
    "repositories": {
        "packagist": {
            "type": "composer",
            "url": "https://packagist.phpcomposer.com"
        }
    }
}

composer install

在proto/src/目录下新建测试用例 login.proto

syntax = "proto3";
package protodata.login;

message C2s_login_begin {
    string open_id = 1;
    string code = 2;
}

生成php对应协议代码文件 protoc --php_out=../gen/ login.proto

注意事项: 1、编写每条协议时首字母必须大写,否则会出现初始化时报错,提示:

PHP Fatal error:  Expect repeated field of different message. in /mnt/work/yangxg/wmgameendor/google/protobuf/phpc/Google/Protobuf/Internal/GPBUtil.php on line 190

创建 start.php 文件,测试协议

<?php

require_once __DIR__ . '/vendor/autoload.php';

$proto_obj = new \Protodata\Login\C2s_login_begin();
$proto_obj->setOpenId('1001');
$proto_obj->setCode('0');

$enmsg = $proto_obj->serializeToString();
echo "encode msg:{$enmsg}\n";

$decode_obj = new \Protodata\Login\C2s_login_begin();
$decode_obj->mergeFromString($enmsg);
$open_id = $decode_obj->getOpenId();
$code = $decode_obj->getCode();
echo "open_id={$open_id}, code={$code}\n";

输出结果:

encode msg:
10010
open_id=1001, code=0

之前与 quick-cocos2dx-lua 进行protobuf协议对接时,由于 quick-cocos2dx-lua 那边最新只支持到 protobuf2.6,php这边使用protbuf3,在进行协议传输对接时发现,只有数字类型和字符串string可以兼容解析到,repeated 类型无法解析