php使用protobuf3


簡介:Google Protocol Buffer(簡稱Protobuf)是google公司內部的混合語言數據標准,目前已經正在使用的有超過48,162種報文格式定義和超過12183個.proto文件。他們用於RPC系統和持續數據存儲系統。

Protocol Buffers是一種輕便高效的結構化數據存儲格式,可以用於結構化數據串行化,或者說序列化。他很適合做數據存儲或RPC數據交換格式。可用於通訊協議,數據存儲等領域的語言無關、平台無關、可擴展的序列化結構格式

安裝protobuf

進入網址:https://github.com/protocolbuffers/protobuf/releases/download/v3.9.1/protobuf-php-3.9.1.tar.gz

下載對應自己需要的安裝包。進行安裝

     進入解壓的安裝包,執行一下命令

     ./configure

     make & make install 

     export PATH = /usr/local/protobuf/bin:$PATH

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

定義proto文件

例如:hello.proto

      syntax = 'proto3';

       package lm;

      message helloworld{

             int32 id = 1 ; 

             string  str = 2;

             int32 opt = 3

      }

      注意這里采用的是proto3的語法,和proto2不太一樣,required和optional的限定已經沒有了,所有字段都是可選的

    編譯生成php文件

     使用上面安裝成功的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文件,就可以進行二進制的讀寫了。

測試二進制讀寫

寫入二進制文件

    

include_once "vendor/autoload.php";
include_once "GPBMetadata/hello.php";
include_once "Lm/hellword.php";

$from = new \Lm\helloword();
$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/helloword.php";

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

protobuf是什么,這么來的
簡單來說就是干和xml一樣的事,把某種數據結構的信息,以某種格式保存起來。主要用於數據存儲、傳輸協議格式等場合。
專業的解答:protocol Buffers是一種輕便高效的結構化數據存儲格式,可用於結構化數據串行化,很適合做數據存儲或RPC數據交換格式。他可用於通訊協議、數據存儲等領域的語言無關、平台無關
可擴展的序列化結構數據格式。

有了xml還搞protobuf原因:
根本原因還是:xml性能不好
1,時間維度:xml格式化(序列化)的開銷倒還好;但是xml解析(反序列化)的開銷就大了
2,空間維度:xml格式為了有較好的可讀性,引入一些冗余的文本信息,所以空間開銷也不是太好。

protobuf有什么好處?
1,對於數據結構的序列化反序列化等性能均優於xml
2,代碼生成機制,使用起來十分方便
3,明星項目有使用:據了解google、新浪、美拍等均有用到protobuf,所以搬到項目肯定不會錯

一,安裝php的protobug擴展

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();

以上用於數據的反序列化。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM