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更多实现,请参阅官方文档快速指南

相关文章
相关标签/搜索