php使用protobuf3, 安装使用

17 篇文章 0 订阅
6 篇文章 0 订阅

摘自:https://www.cnblogs.com/shangfz/p/11475810.html

protobuf 3.1以下版本里并不支持php,需要安装扩展等,建议直接用最新版本3.9.1

简介:Google Protocol Buffer(简称Protobuf)是google公司内部的混合语言数据标准,目前已经正在使用的有超过48,162种报文格式定义和超过12183个.proto文件。他们用于RPC系统和持续数据存储系统。

Protocol Buffers是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。他很适合做数据存储或RPC数据交换格式。可用于通讯协议,数据存储等领域的语言无关、平台无关、可扩展的序列化结构格式

安装protobuf, linux下

以下可以自行选择是否按照,如果是没有安装这些类库,请执行

yum install -y php-pear php5-dev autoconf automake libtool make gcc  gcc-c++

进入网址,下载:wget https://github.com/protocolbuffers/protobuf/releases/download/v3.9.1/protobuf-php-3.9.1.tar.gz

解压:tar -zxvf protobuf-php-3.9.1.tar.gz

进入文件夹:cd protobuf-php-3.9.1 

下载对应自己需要的安装包。进行安装

     进入解压的安装包,执行一下命令

     ./configure

     make & make install 

     #export PATH = /usr/local/protobuf/bin:$PATH #输入报错,不用管

     protoc  --version  //查看是否安装成功

错误及解决方法
protoc: error while loading shared libraries: libprotoc.so.9: cannot open shared
错误原因:protobuf的默认安装路径是/usr/local/lib,而/usr/local/lib 不在Ubuntu体系默认的 LD_LIBRARY_PATH 里,所以就找不到该lib
解决方法:linux 敲击命令:export LD_LIBRARY_PATH=/usr/local/lib
 

------ protoc 安装完成后。

 

需要安装composer,并且修改指定的远程地址为国内的镜像地址 https://www.cnblogs.com/niuben/p/11007804.html 、https://pkg.phpcomposer.com/#how-to-use-packagist-mirror

修改为镜像地址 composer config -g repo.packagist composer https://packagist.phpcomposer.com

项目目录下,定义proto文件,这个文件为配置定义字段顺序配置。

例如:hello.proto

      syntax = 'proto3';

       package lm;

      message helloworld{

             int32 id = 1 ; 

             string  str = 2;

             int32 opt = 3

      }

      注意这里采用的是proto3的语法,和proto2不太一样,required和optional的限定已经没有了,所有字段都是可选的

    编译生成php文件, 会生成 GPBMetadata, Lm 两个文件夹。

     使用上面安装成功的protobuf进行编译proto文件

     protoc hello.proto  --php_out=./

      解释: --php_out :编译输出成php文件

                  --python_out : 编译输出成python文件

   

 这时会在当前目录下,生成一个GPBMetadata的文件夹和LM的文件夹,此时查看lm文件夹下的helloword.php发现它 use了Google\Protobug下的类,这时一个php库,可以去下载。

项目根目录下,右键-》用命令行运行

      composer require google/protobuf

 使用composer引入google/protobuf后,项目种会出现一个vendor目录。在自己的代码中include vendor下的autoload.php,以及刚才生成的helloword.php文件,就可以进行二进制的读写了。

测试二进制读写

比如建一个: test.php

写入二进制文件

    

include_once "vendor/autoload.php";
include_once "GPBMetadata/Hello.php";
include_once "Lm/helloworld.php";

$from = new \Lm\helloworld();
$from->setId(1);
$from->setOpt(29);
$from->setStr("foo bar, this is a message");
$data = $from->serializeToString();
file_put_contents("data.ini",$data);


//读取二进制文件
include_once "vendor/autoload.php";
include_once "GPBMetadata/Hello.php";
include_once "Lm/helloworld.php";

$data = file_get_contents("data.bin");
$to = new \Lm\helloworld();
$to->mergeFromString($data);
echo $to->getId().PHP_EOL;
echo $to->getOpt().PHP_EOL;
echo $to->getStr().PHP_EOL;

注意:如果报错,提示的都是 inlude_once 的错误,请检查 GPBMetadata/ 和 Lm/ 下的2个文件名,跟你引入的文件名,以及 实例化的对象名 是否一致。

protobuf是什么,这么来的
简单来说就是干和xml一样的事,把某种数据结构的信息,以某种格式保存起来。主要用于数据存储、传输协议格式等场合。
  专业的解答:protocol Buffers是一种轻便高效的结构化数据存储格式,可用于结构化数据串行化,很适合做数据存储或RPC数据交换格式。他可用于通讯协议、数据存储等领域的语言无关、平台无关
可扩展的序列化结构数据格式。

有了xml还搞protobuf原因:
根本原因还是:xml性能不好
1,时间维度:xml格式化(序列化)的开销倒还好;但是xml解析(反序列化)的开销就大了
2,空间维度:xml格式为了有较好的可读性,引入一些冗余的文本信息,所以空间开销也不是太好。

protobuf有什么好处?
1,对于数据结构的序列化反序列化等性能均优于xml
2,代码生成机制,使用起来十分方便
3,明星项目有使用:据了解google、新浪、美拍等均有用到protobuf,所以搬到项目肯定不会错

使用方法: *.proto 是 字段顺序配置文件,与你要操作的二进制数据相关联。
比如,在 proto的 message中定义了 1-10个字段, 代码中, 就能set 设置10个字段数据进行存储,以及解析

一,安装php的protobug扩展,(这个只是扩展,而protoc是软件)

wget  https://github.com/allegro/php-protobuf/archive/master.zip
unzip master.zip
cd php-protobuf-master
yum install php-devel(安装依赖包)
phpize
./config --with-php -config=/usr/local/php/bin/php -config
make && make install
//然后在php.ini 里面加一下extension = 'protobuf.so',再重启php与nginx即可

1,代码生成机制:生成proto文件
vim cbstest.proto

message Person{
    required string name =1 ;
    required int32 id =2;
    optional string email = 3;
    optional double money = 4;
}
然后执行 
php ./php-protobuf-master/protoc-gen-php.php cbstest.proto
然后就会形成一个Person.php的文件

<?php
/**
* Auto generated from cbstest.proto 
*/

namespace {
/**
* Person message
*/
class Person extends \ProtobufMessage
{
/* Field index constants */
const NAME = 1;
const ID = 2;
const EMAIL = 3;
const MONEY = 4;

/* @var array Field descriptors */
protected static $fields = array(
self::NAME => array(
'name' => 'name',
'required' => true,
'type' => \ProtobufMessage::PB_TYPE_STRING,
),
...省略...
}

这里会集成ProtobufMessage类,他是在protobuf.so种自动加载的
php实战的用法
对于俺这样非大神的人还是更关注实际的用法,如下

$foo = new Person();
$foo->setName("helloproto");
$foo->setId(2);
$foo->setEmail('helloproto@mail.com');
$foo->setMoney(12323.763);
$packed = $foo->serializeToString();

 

以上packed就是序列化后的结果,可直接存于数据库中

$p = new Person();
$p->parseFromString($packed);
echo $p->getName();
echo $p->getEmail();
echo $p->getMoney();
echo $p->getId();

以上用于数据的反序列化。

PHP常用的使用方法:

序列化:
1、serializeToString:序列化成二进制字符串
2、serializeToJsonString:序列化成JSON字符串
反序列化:
1、mergeFromString:二进制字符串反序列化
2、mergeFromJsonString:Json字符串反序列化

.proto的message解析

1、定义:
类型 变量名=位置;
如:int32 age=1;
这里需要区分,变量名后面的数字意义为该变量内容在二进制序列中的位置而不是变量的值,该数字必须是唯一不可重复使用。
2、目前支持的类型:
double,float,int32,int64,uint32 ,uint64,sint32,sint64
fixed32,fixed64,sfixed32,sfixed64,bool,bytes

相关资料: Protobuf语言指南 https://cloud.tencent.com/developer/article/1520308#

protobuf-php https://cloud.tencent.com/developer/information/protobuf-php

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值