php中使用protobuffer

Protobuf 簡介

protobuf(Protocol buffers)是谷歌出品的跨平臺、跨語言、可擴展的數據傳輸及存儲的協議,是高效的數據壓縮編碼方式之一。php

Protocol buffers 在序列化數據方面,它是靈活的,高效的。相比於 XML 來講,Protocol buffers 更加小巧,更加快速,更加簡單。一旦定義了要處理的數據的數據結構以後,就能夠利用 Protocol buffers 的代碼生成工具生成相關的代碼。甚至能夠在無需從新部署程序的狀況下更新數據結構。只需使用 Protobuf 對數據結構進行一次描述,便可利用各類不一樣語言或從各類不一樣數據流中對你的結構化數據輕鬆讀寫。laravel

Protocol buffers 很適合作數據存儲或 RPC 數據交換格式。可用於通信協議、數據存儲等領域的語言無關、平臺無關、可擴展的序列化結構數據格式。git

此外,Protobuf因爲其在內網高效的數據交換效率,是被普遍應用於微服務的,在谷歌的開源框架grpc便是基於此構建起來的。github

php-protobuf安裝

因爲protobuf原生並不支持php,因此php若是使用pb則須要安裝相應擴展。web

pecl install protobuf

環境中須要有protoc編譯器,下載安裝方式:shell

$ wget https://github.com/google/protobuf/releases/download/v2.5.0/protobuf-2.5.0.tar.gz
$ tar zxvf protobuf-2.5.0.tar.gz
$ cd protobuf-2.5.0
$ ./configure --prefix=/usr/local/protobuf
$ sudo make 
$ sudo  make install

驗證安裝成功:json

$ /usr/local/protobuf/bin/protoc  --version
libprotoc 2.5.0

php-protobuf安裝成功數據結構

php --ri protobuf

安裝lumengoogle/protobuf依賴

lumen new rpc
lumen new rpc命令至關於 composer create-project laravel/lumen rpc
composer require google/protobuf

composer.json下添加classmap:composer

{
    "classmap": [
        "protobuf/"
    ]
}

ok,準備工做都已作好了。框架

本身作一個demo

在代碼目錄下建立一個protobuf文件夾mkdir protobuf

進入該目錄,建立一個文件searchRequest.proto

syntax = "proto3";
message SearchRequest {
    string query = 1;
    int32 page_number = 2;
    int32 result_per_page = 3;
    enum Corpus {
        UNIVERSAL = 0;
        WEB = 1;
        IMAGES = 2;
        LOCAL = 3;
        NEWS = 4;
        PRODUCTS = 5;
        VIDEO = 6;
    }
    Corpus corpus = 4;
}

👇此處很重要👇

composer.json下添加classmap,不然將沒法偵測到對應class
{
   "classmap": [
       "protobuf/"
   ]
}

在命令行下運行:protoc --proto_path=protobuf/ --php_out=protobuf/ protobuf/searchRequest.proto && composer dump-autoload

如今你看到的代碼目錄,應該是這樣的:

clipboard.png

如今,咱們須要的請求類已經獲得了,如今看看如何使用它!

使用

在web.php建立一個路由

$router->get('testp', 'ExampleController@testProtobuf');

ExampleController下添加:

public function testProtobuf()
    {
        // require_once base_path('protobuf/SearchRequest.php');
        $request = new \SearchRequest();
        $request->setPageNumber(67);
        dd($request->getPageNumber());
    }

若是正常打印出67這個數字,就表示該類能夠用,恭喜你已經成功完成了一個請求類的建立。

Go deeper

如今,看一下生成的SearchRequest都有哪些方法:

array:16 [▼
  0 => "__construct"
  1 => "getQuery"
  2 => "setQuery"
  3 => "getPageNumber"
  4 => "setPageNumber"
  5 => "getResultPerPage"
  6 => "setResultPerPage"
  7 => "getCorpus"
  8 => "setCorpus"
  9 => "clear"
  10 => "discardUnknownFields"
  11 => "serializeToString"
  12 => "mergeFromString"
  13 => "serializeToJsonString"
  14 => "mergeFromJsonString"
  15 => "mergeFrom"
]

這裏面帶有set前綴的方法,都是設定對應字段的,帶有get的,都是從buffer中獲取值的,裏面的SerializeToString,建議閱讀官方文檔,裏面有對應的合理的解釋。

和grpc的結合

composer install grpc/grpc

定義Service,這一個須要在client和server兩端都要完成

service RouteGuide {
   rpc GetFeature(Point) returns (Feature) {}
   rpc RecordRoute(stream Point) returns (RouteSummary) {}
   rpc RouteChat(stream RouteNote) returns (stream RouteNote) {}
}

message Point {
  int32 latitude = 1;
  int32 longitude = 2;
}

protoc生成對應的Service實例。

建立一個client

$client = new Routeguide\RouteGuideClient('localhost:50051', [
    'credentials' => Grpc\ChannelCredentials::createInsecure(),
]);

調用RPC服務

$point = new Routeguide\Point();
$point->setLatitude(409146138);
$point->setLongitude(-746188906);
list($feature, $status) = $client->GetFeature($point)->wait();

grpc更多實現,請參閱官方文檔快速指南

相關文章
相關標籤/搜索