language / yii2-protobuf
a wrapper to decode/encode 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-11-18 08:38:45 UTC
README
Yii Protobuf Extension is a wrapper for php protobuf c-extension.It provides an easy way to decode/encoder protobuf data with Yii.In addition to,it provides a tool to generate php proto files from .proto.
You must install php c-ext before you can use this extension
Requirements
To use PHP runtime library requires:
- C extension:protobuf >= 3.5.0
- PHP package:php >= 7.0.0
- Yii2.0 or above
Installation
You can install this extension by composer, as follows:
composer require language/yii2-protobuf
Configure
You need to add protobuf parser/formatter for request/response Component, as follows:
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. ], ], ], ... ], ]
As you can see, this extension use application/x-protobuf
Content-Type to distinguish protobuf binary data.So, Client should set Content-Type as
application/x-protobuf
when it send protobuf binary data to Server
Generate Proto
You can run build.sh shell script to generate proto files after Editing msg.proto. it will generate PbApp
and GPBMetadata
.You should always edit .proto instead of editing generated proto files
bash build.sh
Register Proto
You need to register .proto.php files for encode protobuf data after generate proto files.You can create a base controller and register them, As follows:
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 provides asProtobuf
method to convert php hash table to protobuf data
Usage
You should alway get request params with $request->getBodyParams()
intead of $_REQUEST
.ProtobufParser parser protobuf to array
<?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]); } }
Sample
�
�xxxx��xxxx�d ����
�home�
�153xxxx6476��
�company�
�188xxxx7049�
�Beijing�
�Hangzhou
Customized Request Struct
By default, protobuf parser can only parser map<string,string> protobuf data as message-defined proto
message Request { map<string,string> Headers = 1; // Header Params map<string,string> BodyParams = 2; // Body Params }
You can define your request proto, as follows
message Meta{ repeated Params = 1; } message MyRequest { map<string,Meta> Headers = 1; // Header Params map<string,Meta> BodyParams = 2; // Body Params }
Then, you should tell ProtobufFormatter which class to serialize Array Data
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' ], ], ], ... ], ]
If you need more flexiable data-struct, you can parser the protobuf raw data, as follows:
message UserMsgLoginREQ{ string UserName = 1; string Password = 2; } message FlexiableRequest { string ProtoClass = 1; // proto class to parser bytes ProtoData = 2; // bytes protobuf data }
FlexiableRequest is a internal proto define. So, don't change the message name.