language/yii2-protobuf

用于解码/编码 protobuf 的包装器

1.0.1-stable 2018-12-08 15:06 UTC

This package is not auto-updated.

Last update: 2024-09-23 07:50:58 UTC


README

Yii Protobuf 扩展是 php protobuf c 扩展的包装器。php protobuf c 扩展。它提供了一个简单的途径来使用 Yii 解码/编码 protobuf 数据。此外,它提供了一个工具,可以从 .proto 文件生成 php proto 文件。

在使用此扩展之前,您必须安装 php c-ext

要求

要使用 PHP 运行时库需要

  • C 扩展:protobuf >= 3.5.0
  • PHP 包:php >= 7.0.0
  • Yii2.0 或更高版本

安装

您可以通过 composer 安装此扩展,如下所示

composer require language/yii2-protobuf

配置

您需要为请求/响应组件添加 protobuf 解析器/格式化程序,如下所示

return [
    ...
    'components' => [
            ...
        'request' => [
            // !!! insert a secret key in the following (if it is empty) - this is required by cookie validation
            'cookieValidationKey' => 'inwyiHVV0KPon5UhGv6l0QYaWL4SC1ww',
            'parsers' => [
                'application/x-protobuf' => 'Language\Protobuf\ProtobufParser'
            ],
        ],
        'response' => [
            'formatters'=>[
                'protobuf' => [
                    'class'=>'Language\Protobuf\ProtobufResponseFormatter',
                    'hump'=>true, //By default, the field name is underlined to hump, for example, iphone_num is converted to IphoneNum.
                ],
            ],
        ],
        ...
    ],
]

如您所见,此扩展使用 application/x-protobuf Content-Type 来区分 protobuf 二进制数据。因此,客户端在向服务器发送 protobuf 二进制数据时,应将 Content-Type 设置为 application/x-protobuf

生成 Proto

在编辑 msg.proto 后,您可以通过运行 build.sh 脚本来生成 proto 文件。它将生成 PbAppGPBMetadata。您应始终编辑 .proto 文件,而不是编辑生成的 proto 文件

bash build.sh

注册 Proto

在生成 proto 文件后,您需要注册 .proto.php 文件以编码 protobuf 数据。您可以创建一个基础控制器并将它们注册,如下所示

class BaseController extends Controller
{
    use ProtobufTrait;  //Inject using the trait attribute asProtobuf method

    public function init()
    {
        parent::init();
        // 消息文件注册
        ProtobufManager::register(ROOT . '/proto/msg.proto.php');
    }
}

ProtobufTrait 提供了 asProtobuf 方法,用于将 PHP 哈希表转换为 protobuf 数据

使用方法

您应该始终使用 $request->getBodyParams() 获取请求参数,而不是使用 $_REQUEST。ProtobufParser 将 protobuf 解析为数组

<?php
/**
 * Created by PhpStorm.
 * User: liugaoyun
 * Date: 2018/12/1
 * Time: 下午9:10
 */

namespace frontend\controllers;


use Language\Protobuf\ProtobufTrait;
use yii\base\Controller;

class TestController extends Controller
{

    public function actionProtobuf(){
        //params
        $params = \Yii::$app->getRequest()->getBodyParams();

        //TODO:your logic

        //convert array to protobuf
        $data = [
            'UserInfo'=>[
                'OpenUid'=>'xxxx',
                'NickName'=>'xxxx',
                'Age'=>100,
                'Param1'=>1000
            ],
            'AddrList'=>[
                'home'=>[
                    'Address'=>'addr1',
                    'IphoneNum'=>'153xxxx6476'
                ],
                'company'=>[
                    'Address'=>'addr2',
                    'IphoneNum'=>'188xxxx7049'
                ],
            ],
            'GoneCities'=>[
                ['Name'=>'Beijing'],
                ['Name'=>'Hangzhou'],
            ]
        ];


        return $this->asProtobuf(['class'=>'PbApp\UserLoginACK', 'data'=>$data]);
    }
}

示例


�
�xxxx��xxxx�d ����
�home�
�153xxxx6476��
�company�
�188xxxx7049�	
�Beijing�

�Hangzhou

自定义请求结构

默认情况下,protobuf 解析器只能解析 map protobuf 数据作为消息定义的 proto

message Request
{
    map<string,string>  Headers  = 1;			// Header Params
    map<string,string>  BodyParams  = 2;         // Body Params
}

您可以定义自己的请求 proto,如下所示

message Meta{
    repeated    Params = 1;
}

message MyRequest
{
     map<string,Meta>  Headers  = 1;			// Header Params
        map<string,Meta>  BodyParams  = 2;         // Body Params
}

然后,您需要告诉 ProtobufFormatter 何时序列化数组数据

return [
   ...
   'components' => [
           ...
       'response' => [
           'formatters'=>[
               'protobuf' => [
                   'class'=>'Language\Protobuf\ProtobufResponseFormatter',
                   'hump'=>true, //By default, the field name is underlined to hump, for example, iphone_num is converted to IphoneNum.
                   'requestProtoClass'=>'PbApp\MyRequest'
               ],
           ],
       ],
       ...
   ],
]

如果您需要更灵活的数据结构,您可以解析 protobuf 原始数据,如下所示

message UserMsgLoginREQ{
    string  UserName = 1;
    string  Password = 2;
}

message FlexiableRequest
{
    string ProtoClass  = 1;         // proto class to parser
    bytes  ProtoData  = 2;         // bytes protobuf data
}

FlexibleRequest 是内部 proto 定义。因此,不要更改消息名称。