language / yii2-protobuf
用于解码/编码 protobuf 的包装器
Requires
- php: >=7.0.0
- ext-protobuf: >=3.5.0
- yiisoft/yii2: ~2.0.0
Requires (Dev)
- phpunit/phpunit: ^6.2
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 文件。它将生成 PbApp
和 GPBMetadata
。您应始终编辑 .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 解析器只能解析 mapproto
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 定义。因此,不要更改消息名称。