目录
一、什么是protobuf
protobuf,全称:Protocol buffers,是 Google 用于序列化结构化数据的语言中立、平台中立、可扩展机制——想想 XML,JSON,但更小、更快、更简单。您只需定义一次数据的结构化方式,然后就可以使用特殊生成的源代码轻松地将结构化数据写入和读取各种数据流,并使用各种语言
二、protobuf3跟protobuf2的区别
总的来说,protobuf3比protobu2支持更多的语法,而且相对比之下protobuf3更简洁。protobuf3去掉了一些复杂的语法和特性,更加强调约定而弱化了语法。如果贵公司是首次使用protobuf的话个人还是建议直接上protobuf3。
三、在php业务场景里面安装使用protobuf2.6
1、linux安装protobuf使用命令
由于php已经支持protobuf3,这里就不说protobuf3以上的版本,如果你跟我一样公司对接外部业务需求protobuf2,那就只能用到第三方组件。话不多说,直接上protobuf2的Demo例子。
wget https://github.com/protocolbuffers/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gz
tar zxvf protobuf-2.6.1.tar.gz
cd protobuf-2.6.1
./configure --prefix=/usr/local/protobuf
make && make install
export PATH=/usr/local/protobuf/bin:$PATH
protoc --version
2、安装protobuf拓展
wget https://github.com/allegro/php-protobuf/archive/master.zip
unzip master.zip
cd php-protobuf-master
phpize
./configure --with-php-config=$PATH//注:这里的$PATH是你php路径下的php-config路径
make && make install
//然后在php.ini里面加一下extension = protobuf.so,再重启php-fpm
3、生成对应的类库文件
首先我们的需要一个proto模板,这个是交互双方相互约定,这里就不做过多赘述,直接上proto的Demo。
syntax = "proto2";//注:protobuf2可以不设置syntax,他默认就是proto2
package test;
message PhoneNumber {
required string number = 1;
required int32 type = 2;
}
message Person {
required string name = 1;
required int32 id = 2;
optional string email = 3;
repeated PhoneNumber phone = 4;
optional double money = 5;
}
message AddressBook {
repeated Person person = 1;
}
这里保存为.proto文件即可,然后进入到php-protobuf-master目录,执行下面的命令。
curl -s http://getcomposer.org/installer | php
php composer.phar install
php ./php-protobuf-master/protoc-gen-php.php DmpDataProto.proto
执行完上述操作之后会生成下列文件
生成的这几个文件是可以直接引入到自己项目文件里面使用的。
4、自动加载
在使用代码之前,我们需要手动配置autoload,就直接在项目根目录文件下面composer.json的psr4加上命名空间
"autoload": {
"psr-4": {
"Test\\": "Test"
},
"files": []
}
配置完composer.json之后注意需要执行composer dump-autoload,使其自动加载。
5、代码的使用
下面是简单的Demo,仅供参考。在写protobuf2之前需要在自己的项目里面引入第三方组件,这边做过很多调研,加上php已经支持protobuf3,所以大多数的protobuf第三方组件都已经弃用了,经过多次踩坑经历个人比较推荐使用allegro/php-protobuf。
public function index()
{
$foo = new \Test\Person();
$foo->setName('abc');
$foo->setId(1);
$foo->setEmail('abc');
$foo->setMoney(321321.32);
$phone_num = new \Test\PhoneNumber();
$phone_num->setNumber('16589875625');
$phone_num->setType(3);
$foo->appendPhone($phone_num);
$packed = $foo->serializeToString();
var_dump($packed);
echo "-----------src------------\n";
echo $foo->getName() ."\n";
echo $foo->getPhone()[0]->getNumber() ."\n";
$foo->dump();
echo "------------------------\n\n\n";
try {
$p = new \Test\Person();
$p->parseFromString($packed);
echo "------------parsed-------\n";
echo $p->getName() ."\n";
echo $p->getEmail() ."\n";
echo $p->getMoney() ."\n";
echo $p->getId() . "\n";
echo $p->getPhone()[0]->getNumber() ."\n";
echo "------------------------\n";
} catch (Exception $ex) {
die('Upss.. there is a bug in this example');
}
}
返回:
写倒最后:该文章是通过整理其他文章整理而得。