protoc gen php,让你的php框架支持protobuf

一.protoc 工具生成

1.1 安装依赖扩展

[详细教程]

1.2 使用protoc工具生成对应的php类

由于protobuf扩展封装在框架的extend目录下面,路径: /casualgame/extend/socket/protobuf

以生成一个person类为例:

step1:创建person的protobuf定义文件:persongpb.proto

syntax="proto3";

package extend.socket.protobuf.person;//person类的命名空间,跟框架路径定义一致

message Person{

string name=1;//姓名

int32 age=2;//年龄

bool sex=3;//性别

}

1

2

3

4

5

6

7

syntax="proto3";

packageextend.socket.protobuf.person;//person类的命名空间,跟框架路径定义一致

messagePerson{

stringname=1;//姓名

int32age=2;//年龄

boolsex=3;//性别

}

step2:

生成Person类

切换到/casualgame/extend/socket/protobuf目录

执行命令:

> protoc –php_out=./ persongpb.proto

说明:

第一个参数

php_out表示生成php类

–php_out=./ 表示把php类生成在当前目录下

第二个参数

persongpb.proto表示使用persongpb.proto定义文件

这样会在/casualgame/extend/socket/protobuf目录下创建

Extend/Socket/Protobuf/Person这几个新目录,并且我们想要的Person类在该目录下面。

把Peroson/Person.php复制到/casualgame/extend/socket/protobuf目录下即可。

step3:

通过composer注册psr4命名空间

第一步:配置composer.json

php

{

"require": {

"monolog/monolog": "1.0.*",

"overtrue/pinyin": "~4.0",

"google/protobuf": "^3.8"

},

"autoload": {

"psr-4": {

"Monolog\\": "src/",

"Extend\\": "extend/",

"Extend\\Socket\\Protobuf\\":"extend/socket/protobuf/",

"GPBMetadata\\":"extend/socket/protobuf/GPBMetadata/"

}

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

php

{

"require":{

"monolog/monolog":"1.0.*",

"overtrue/pinyin":"~4.0",

"google/protobuf":"^3.8"

},

"autoload":{

"psr-4":{

"Monolog\\":"src/",

"Extend\\":"extend/",

"Extend\\Socket\\Protobuf\\":"extend/socket/protobuf/",

"GPBMetadata\\":"extend/socket/protobuf/GPBMetadata/"

}

}

}

红色部分为新加的命名空间,跟Person.php中的命名空间一致。执行composer install

会在/casualgame/vendor/composer/autoload_psr4.php文件下生成命名空间配置:

框架在自动加载的时候根据命名空间别名帮我们加载到我们想加载的文件。

> PS:如果对composer使用不熟的要好好复习一下。

示例(php向goserver请求获取用户信息)

1)定义格式文件

server.proto

syntax="proto2";

package extend.socket.protobuf.server;//命名空间

message PhpPlayer

{

required int32 uid = 1;

repeated PhpFieldData fields = 2;

optional int32 ret = 3; //0:成功 1-失败

}

message PhpFieldData

{

required string fieldname = 1;//例如money diamond exp

optional int64 fieldvalue = 2;

}

message PhpBroad2Client

{

repeated int32 uids = 1;//广播用户id

required string data = 2;//广播数据 json格式

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

syntax="proto2";

packageextend.socket.protobuf.server;//命名空间

messagePhpPlayer

{

requiredint32uid=1;

repeatedPhpFieldDatafields=2;

optionalint32ret=3;//0:成功 1-失败

}

messagePhpFieldData

{

requiredstringfieldname=1;//例如money diamond exp

optionalint64fieldvalue=2;

}

messagePhpBroad2Client

{

repeatedint32uids=1;//广播用户id

requiredstringdata=2;//广播数据 json格式

}

PS:对protobuf语法不熟悉的研究一下。[传送门](https://colobu.com/2015/01/07/Protobuf-language-guide/ “传送门”)

具体用法test.php:

require_once 'PhpBroad2Client.php';//引入需要的protobuf工具类

require_once 'PhpFieldData.php';

require_once 'PhpPlayer.php';

$client = new \Serverpb\PhpBroad2Client();

$client->appendUids(10001);//设置PhpBroad2Client的uids值

$data = new \Serverpb\PhpFieldData();

$data->setFieldname("money");

$data->setFieldvalue(1000);

$player = new \Serverpb\PhpPlayer();

$player->setUid(10002);

$player->appendFields($data);

$player->setRet(1);

$packed = $player->serializeToString();

var_dump($packed);

$parsed = new \Serverpb\PhpPlayer();

try {

$parsed->parseFromString($packed);

} catch (Exception $ex) {

die('Oops.. there is a bug in this example, ' . $ex->getMessage());

}

$parsed->dump();

die("end");

?>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

require_once'PhpBroad2Client.php';//引入需要的protobuf工具类

require_once'PhpFieldData.php';

require_once'PhpPlayer.php';

$client=new\Serverpb\PhpBroad2Client();

$client->appendUids(10001);//设置PhpBroad2Client的uids值

$data=new\Serverpb\PhpFieldData();

$data->setFieldname("money");

$data->setFieldvalue(1000);

$player=new\Serverpb\PhpPlayer();

$player->setUid(10002);

$player->appendFields($data);

$player->setRet(1);

$packed=$player->serializeToString();

var_dump($packed);

$parsed=new\Serverpb\PhpPlayer();

try{

$parsed->parseFromString($packed);

}catch(Exception$ex){

die('Oops.. there is a bug in this example, '.$ex->getMessage());

}

$parsed->dump();

die("end");

?>

2)整合到框架中

执行以下命令:

> php /data/wwwroot/php-protobuf-0.12.4/protoc-gen-php.php server.proto

同样在/casualgame/extend/socket/protobuf/Extend/Socket/Protobuf/Server文件夹下会生成

PhpBroad2Client.php PhpFieldData.php PhpPlayer.php三个文件。把整个Server目录拷贝到

/casualgame/extend/socket/protobuf/ 目录下,使用的时候引入三个工具类的命名空间。

使用:

namespace extend\socket;

use Extend\Socket\Protobuf\Server\PhpBroad2Client;

use Extend\Socket\Protobuf\Server\PhpFieldData;

use Extend\Socket\Protobuf\Server\PhpPlayer;

class test{

public static function test(){

$client = new PhpBroad2Client();

$client->appendUids(10001);

$data = new PhpFieldData();

$data->setFieldname("money");

$data->setFieldvalue(1000);

$player = new PhpPlayer();

$player->setUid(10002);

$player->appendFields($data);

$player->setRet(1);

$packed = $player->serializeToString();

$parsed = new PhpPlayer();

try {

$parsed->parseFromString($packed);

} catch (Exception $ex) {

die('Oops.. there is a bug in this example, ' . $ex->getMessage());

}

$parsed->dump();

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

namespaceextend\socket;

useExtend\Socket\Protobuf\Server\PhpBroad2Client;

useExtend\Socket\Protobuf\Server\PhpFieldData;

useExtend\Socket\Protobuf\Server\PhpPlayer;

classtest{

publicstaticfunctiontest(){

$client=newPhpBroad2Client();

$client->appendUids(10001);

$data=newPhpFieldData();

$data->setFieldname("money");

$data->setFieldvalue(1000);

$player=newPhpPlayer();

$player->setUid(10002);

$player->appendFields($data);

$player->setRet(1);

$packed=$player->serializeToString();

$parsed=newPhpPlayer();

try{

$parsed->parseFromString($packed);

}catch(Exception$ex){

die('Oops.. there is a bug in this example, '.$ex->getMessage());

}

$parsed->dump();

}

}

PS:如果提示找不到相关class的话,只需要去composer.json psr4选项注册对应的命名空间。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值