tars2php 使用说明

简介

tars2php主要功能是通过tars协议文件,自动生成client端和server端php代码,方法大家使用。(server端主要为框架代码,实际业务逻辑需要自己补充实现)

基本类型的映射

如下是我们对基本类型的映射:

  1. bool => \TARS::BOOL
  2. char => \TARS::CHAR
  3. uint8 => \TARS::UINT8
  4. short => \TARS::SHORT
  5. uint16 => \TARS::UINT16
  6. float => \TARS::FLOAT
  7. double => \TARS::DOUBLE
  8. int32 => \TARS::INT32
  9. uint32 => \TARS::UINT32
  10. int64 => \TARS::INT64
  11. string => \TARS::STRING
  12. vector => \TARS::VECTOR
  13. map => \TARS::MAP
  14. struct => \TARS::STRUCT

当我们需要标识具体的变量类型的时候,就需要用到这些基本的类型了,这些类型都是常量,从1-14。

复杂类型的映射

针对vector、map、struct三种基本的类型,有一些特殊的打包解包的机制,因此需要引入特别的数据类型: vector:

  1. vector => \TARS_VECTOR
  2. 它同时具有两个成员函数pushBack()和push_back()
  3. 入参为取决于vector本身是包含什么类型的数组
  4. 例如:
  5. $shorts = ["test1","test2"];
  6. $vector = new \TARS_VECTOR(\TARS::STRING); //定义一个string类型的vector
  7. foreach ($shorts as $short) {
  8. $vector->pushBack($short); //依次吧test1,test2两个元素,压入vector中
  9. }

map:

  1. map => \TARS_MAP
  2. 它同时具有两个成员函数pushBack()和push_back()
  3. 入参为取决于map本身包含什么类型
  4. 例如:
  5. $strings = [["test1"=>1],["test2"=>2]];
  6. $map = new \TARS_MAP(\TARS::STRING,\TARS::INT64); //定义一个key为string,value是int64的map
  7. foreach ($strings as $string) {
  8. $map->pushBack($string); //依次把两个元素压入map中,注意pushBack接收一个array,且array只有一个元素
  9. }

struct:

  1. struct => \TARS_Struct
  2. struct的构造函数比较特殊,接收classnameclassfields两个参数
  3. 第一个描述名称,第二个描述struct内的变量的信息
  4. 例如:
  5. class SimpleStruct extends \TARS_Struct {
  6. const ID = 0; //TARS文件中每个struct的tag
  7. const COUNT = 1;
  8. public $id; //strcut中每个元素的值保存在这里
  9. public $count;
  10. protected static $fields = array(
  11. self::ID => array(
  12. 'name'=>'id',//struct中每个元素的名称
  13. 'required'=>true,//struct中每个元素是否必须,对应tars文件中的require和optional
  14. 'type'=>\TARS::INT64,//struct中每个元素的类型
  15. ),
  16. self::COUNT => array(
  17. 'name'=>'count',
  18. 'required'=>true,
  19. 'type'=>\TARS::UINT8,
  20. ),
  21. );
  22. public function __construct() {
  23. parent::__construct('App_Server_Servant.SimpleStruct', self::$fields);
  24. }
  25. }

tars2php使用方法

如果用户只有使用打包解包需求的,那么使用流程如下:

  1. 准备一份tars协议文件,例如example.tars
  2. 编写一个tars.proto.php文件,这是用来生成代码的配置文件。
  1. //本范例的servant name为PHPTest.PHPServer.obj
  2. return array(
  3. 'appName' => 'PHPTest', //tars服务servant name 的第一部分
  4. 'serverName' => 'PHPServer', //tars服务servant name 的第二部分
  5. 'objName' => 'obj', //tars服务servant name 的第三部分
  6. 'withServant' => true,//决定是服务端,还是客户端的自动生成
  7. 'tarsFiles' => array(
  8. './example.tars' //tars文件的地址
  9. ),
  10. 'dstPath' => './server/', //生成php文件的位置
  11. 'namespacePrefix' => 'Server\servant', //生成php文件的命名空间前缀
  12. );
  1. 执行php ./tars2php.php ./tars.proto.php
  2. 工具会根据servant name自动生成三级目录结构,demo中会在./server目录下生成PHPTest/PHPServer/obj/目录,obj目录下的classers是struct对应的php对象,tars目录是tars协议文件本身 。

如example.tars中的struct:

  1. struct SimpleStruct {
  2. 0 require long id=0;
  3. 1 require unsigned int count=0;
  4. 2 require short page=0;
  5. };

转变成classes/SimpleStruct.php

  1. <?php
  2. namespace Server\servant\PHPTest\PHPServer\obj\classes;
  3. class SimpleStruct extends \TARS_Struct {
  4. const ID = 0; //tars协议中的tag
  5. const COUNT = 1;
  6. const PAGE = 2;
  7. public $id; //元素的实际值
  8. public $count;
  9. public $page;
  10. protected static $_fields = array(
  11. self::ID => array(
  12. 'name'=>'id', //tars协议中没个元素的name
  13. 'required'=>true, //tars协议中是require或者optional
  14. 'type'=>\TARS::INT64, //类型
  15. ),
  16. self::COUNT => array(
  17. 'name'=>'count',
  18. 'required'=>true,
  19. 'type'=>\TARS::UINT32,
  20. ),
  21. self::PAGE => array(
  22. 'name'=>'page',
  23. 'required'=>true,
  24. 'type'=>\TARS::SHORT,
  25. ),
  26. );
  27. public function __construct() {
  28. parent::__construct('PHPTest_PHPServer_obj_SimpleStruct', self::$_fields);
  29. }
  30. }
  1. 以example.tars中的interface部分会自动生成单独的已interface命名的php文件。 例如int testLofofTags(LotofTags tags, out LotofTags outtags);接口生成的方法如下

server部分

  1. <?php
  2. //注意生成文件中的注释部分会在server启动的时候转换为php代码,如非必要,请勿修改.
  3. //server部分具体实现需要自己继承完成,注释说明依次如下
  4. //参数为struct类型,对应$tags变量,对应的php对象在\Server\servant\PHPTest\PHPServer\obj\classes\LotofTags
  5. //参数为struct类型,对应$outtags变量,对应的php对象在\Server\servant\PHPTest\PHPServer\obj\classes\LotofTags,是输出参数
  6. //接口防止为int
  7. /**
  8. * @param struct $tags \Server\servant\PHPTest\PHPServer\obj\classes\LotofTags
  9. * @param struct $outtags \Server\servant\PHPTest\PHPServer\obj\classes\LotofTags =out=
  10. * @return int
  11. */
  12. public function testLofofTags(LotofTags $tags,LotofTags &$outtags);

client部分

  1. <?php
  2. try {
  3. $requestPacket = new RequestPacket(); //构建请求包需要的参数
  4. $requestPacket->_iVersion = $this->_iVersion;
  5. $requestPacket->_funcName = __FUNCTION__;
  6. $requestPacket->_servantName = $this->_servantName;
  7. $encodeBufs = [];
  8. $__buffer = TUPAPIWrapper::putStruct("tags",1,$tags,$this->_iVersion); //打包第一个参数tags
  9. $encodeBufs['tags'] = $__buffer;
  10. $requestPacket->_encodeBufs = $encodeBufs; //在请求包中设置请求bufs
  11. $sBuffer = $this->_communicator->invoke($requestPacket,$this->_iTimeout); //发送请求包,接收返回包
  12. $ret = TUPAPIWrapper::getStruct("outtags",2,$outtags,$sBuffer,$this->_iVersion); //从返回包中解出第一个输出参数outtags
  13. return TUPAPIWrapper::getInt32("",0,$sBuffer,$this->_iVersion); //解出返回参数 返回参数 name是空,tag为0
  14. }
  15. catch (\Exception $e) {
  16. throw $e;
  17. }