php protobuf 3の使い方

4645 ワード

概要
Google Protocol Buffer(略称Protobuf)はGoogle社内のハイブリッド言語データ標準であり、現在使用されているのは48162種類以上のメッセージフォーマット定義と12183個以上である.protoファイル.RPCシステムと継続的なデータストレージシステムに使用されます.
Protocol Buffersは、構造化データのシリアル化、またはシーケンス化に使用できる軽量で効率的な構造化データストレージフォーマットです.データストレージやRPCデータ交換フォーマットに適しています.通信プロトコル、データストレージなどの分野で使用できる言語無関係、プラットフォーム無関係、拡張可能なシーケンス化構造データフォーマット.現在、C++、Java、Pythonの3言語のAPIが提供されている.
シリアル番号解析の原理も参照してください.https://www.cnblogs.com/naci/p/5341433.html
客観的に言えば、protobufはphpによくサポートされていないような気がします.複雑なデータ構造を書くのは面倒です.自分の不足かもしれない.
 
protobufのインストール
Webサイトにアクセス:https://github.com/protocolbuffers/protobuf/releases
必要なインストールパッケージをダウンロードします.インストール
        ,      :

./configure
make && make install

        ,                ,     ,   protobuf   
protoc --version

 
protoファイルの定義
例:hello.proto
syntax = "proto3";
package lm;

message helloworld
{
    int32 id = 1; // ID
    string str = 2; // str
    int32 opt = 3; // optional field
}

注意:ここではproto 3の構文を採用していますが、proto 2とは異なり、requiredoptionalの限定はもうなく、すべてのフィールドがオプションです.proto 3はproto 2とどんな違いがありますか?
 
コンパイルphpファイルの生成
         protobuf    proto  

protoc hello.prot --php_out=./ 

  :
    --php_out :     php  
    --python_out :     python  
    
  

このとき、現在のディレクトリの下にGPBMetadataのフォルダとLmのフォルダが生成され、lmフォルダの下のhelloworldが表示されます.phpファイル
中のコードを読んでみると、Google\Protobufのクラスがuseされています.これはPHPライブラリで、ダウンロードできます.
https://github.com/google/protobuf/tree/master/php/src/Google/Protobuf
composerでプロジェクトに導入することもできます.composerでAutoloaderを自動的に生成することができるので、composerで導入することをお勧めします.
composer require google/protobuf

composer方式でgoogle/protobufを導入すると、プロジェクトにvendorディレクトリが表示されます.自分のコードの中でinclude vendorの下のautoload.phpと、さっき生成したhelloworld.phpのファイルで、バイナリの読み書きができます
 
バイナリ読み書きのテスト
バイナリファイルの書き込み
setId(1); 
$from->setStr('foo bar, this is a message'); 
$from->setOpt(29); 
$data = $from->serializeToString(); 
file_put_contents('data.bin', $data);

バイナリファイルの読み込み
mergeFromString($data); 
echo $to->getId() . PHP_EOL; 
echo $to->getStr() . PHP_EOL; 
echo $to->getOpt() . PHP_EOL;

実はここまで书くと、読むのが面倒なことに気づくかもしれませんが、パラメータが多いと一つ一つ印刷されるのではないでしょうか.だから、私は最后にpythonで解析したので、一つの方法で自動的に全部読みました.
 
pythonによる解析バイナリファイル
作成するpyファイル
# -*- coding: utf-8 -*-
import hello_pb2
import sys

helloworld = hello_pb2.helloworld()
f = open(sys.argv[1],'rb')
helloworld.ParseFromString(f.read())
print helloworld



  :
    hello_pb2:  protoc hello.proto --python_out=./       
    
       python     (      data        ):python test.py ./data

以上が著者全体が使用する過程である
 
*phpのprotobuf拡張をインストールすると、複数のパラメータの使い捨て印刷の問題を解決できると言われています
ここで私も方法を書きますが、本人がインストールした後、実行ファイルが間違っているので、後者にアドバイスしてほしいです.
 
一、phpのprotobuf拡張をインストールする
  php    bin   ,       pecl  ,        

./pecl install protobuf


    , php.ini     protobuf   
  php  

二、php拡張をインストールし、バイナリファイルを読み書きする
//  
public function encode($data){
    $fields = $this->fields();
    foreach ($fields as $key => $_item) {
        $field_name = $_item['name'];
        if(isset($data[$field_name])) {
            $this->set($key, $data[$field_name]);
        }
    }

    try {
        $packed = $this->serializeToString();
    } catch (\Exception $ex) {
        $data['fields'] = $fields;
        $data['error']  = $ex->getMessage();
        writeLog($data, 'encode_new_pb_failed');
        $packed = '';
    }

    return $packed;
}

//  
public function decode($packed){
    try {
        $this->parseFromString($packed);

    } catch (\Exception $ex) {
        writeLog($ex->getMessage(), 'decode_new_pb_failed');
    }

    $data = array();
    $fields = $this->fields();
    foreach ($fields as $key => $_item) {
        $field_name = $_item['name'];
        $data[$field_name] = $this->get($key);
    }

    return $data;
}

インストール拡張後の操作に基づいて、著者は成功せず、デバッグする時間もありません.参考にしてください.スプレーしないでください