Google's Protobuf之PHP示例用法说明
搜了一遍,好像对PHP使用Protobuf的博文好少好少,因为公司有项目用到,所以这边也进行了解了一下。
google官方没有php版的使用说明,示例以allegro的php-protobuf进行说明,参考地址见本文最后面。
1. 安装php的protobuf扩展(linux)
从 https://github.com/allegro/php-protobuf 下载源代码
1) 进入源代码
2) /{php的bin目录}/phpize
3) ./configure
4) make && make install
5) 在php.ini里加入 extension=protobuf.so
6) 重启php
7) 用php -m 或 phpinfo() 查看扩展有没有安装成功
2. php的protobuf扩展说明
1) 继承ProtobufMessage类
2) 值的类型说明
const PB_TYPE_DOUBLE = 1; const PB_TYPE_FIXED_32 = 2; const PB_TYPE_FIXED_64 = 3; const PB_TYPE_FLOAT = 4; const PB_TYPE_INT = 5; const PB_TYPE_SIGNED_INT = 6; const PB_TYPE_STRING = 7; const PB_TYPE_BOOL = 8;
3) 属性字段的类型说明
required: 必须
optional: 可选
repeated: 多值
4) required/optional实现的方法
get{FIELD}() // return field value set{FIELD}($value) // set field value to $value
5) repeated实现的方法
append{FIELD}($value) // append $value value to field
clear{FIELD}() // empty field
get{FIELD}() // return array of field values
getAt{FIELD}($index) // return field value at $index index
getCount{FIELD}() // return number of field values
getIterator{FIELD}($index) // return ArrayIterator for field values
3. php如何使用protobuf
首先声明一个ProtobufMessage的子类,示例:
1 <?php 2 /** 3 * 人 4 * 声明一个ProtobufMessage的子类 5 * 要实现ProtobufMessage里的抽象方法reset 6 * 7 */ 8 class Person extends ProtobufMessage{ 9 /** 10 * 属性字段索引定义 11 */ 12 const NAME = 1; //姓名 13 const AGE = 2; //年龄 14 const CARS = 3; //拥有的汽车 15 16 /** 17 * type的定义值如下: 18 * 19 * 1:double; 2:fixed_32; 3:fixed_64; 4:float; 5:int; 6:signed int; 7:string; 8:bool; 20 * 21 */ 22 protected static $fields = array( 23 self::NAME => array( 24 'name' => 'name', 25 'required' => true, //required:必填,optional:可选 26 'type' => 7 27 ), 28 self::AGE => array( 29 'name' => 'age', 30 'required' => true, 31 'type' => 5 32 ), 33 self::CARS => array( 34 'name' => 'cars', 35 'repeated' => true, //repeated:多值,数组或对象 36 'type' => 7 37 ) 38 ); 39 40 public function __construct() { 41 $this->reset(); 42 } 43 44 public function reset() { 45 $this->values[self::NAME] = null; 46 $this->values[self::AGE] = null; 47 $this->values[self::CARS] = array(); 48 } 49 50 public function fields() { 51 return self::$fields; 52 } 53 54 /** 55 * required/optional类型的字段 56 * 要实现两个方法: set{FIELD}($value) 57 * get{FIELD}() 58 * 59 * 以上方法非必须 60 */ 61 62 /** 63 * 获得名字 64 * @return string 65 */ 66 public function getName() { 67 return $this->get(self::NAME); 68 } 69 70 /** 71 * 设置名字 72 * @param string $name 73 * @return bool 74 */ 75 public function setName($name) { 76 return $this->set(self::NAME, $name); 77 } 78 79 /** 80 * 获得年龄 81 * @return int 82 */ 83 public function getAge() { 84 return $this->get(self::AGE); 85 } 86 87 /** 88 * 设置年龄 89 * @param int $age 90 * @return bool 91 */ 92 public function setAge($age) { 93 return $this->set(self::AGE, $age); 94 } 95 96 /** 97 * repeated类型的字段 98 * 要实现多值型的方法: append{FIELD}($value) 99 * clear{FIELD}() 100 * get{FIELD}() 101 * get{FIELD}At($index) 102 * get{FIELD}Count() 103 * get{FIELD}Iterator() 104 * 105 * 以上这些方法非必须,命名方式也非必须,但最好有个统一的命名规则 106 */ 107 108 /** 109 * 追加值 110 * 111 * @param string $car 112 * @return bool 113 */ 114 public function appendCars($car) { 115 return $this->append(self::CARS, $car); 116 } 117 118 /** 119 * 清除值 120 * @return bool 121 */ 122 public function clearCars() { 123 return $this->clear(self::CARS); 124 } 125 126 /** 127 * 获得值 128 * @return array 129 */ 130 public function getCars() { 131 return $this->get(self::CARS); 132 } 133 134 /** 135 * 获得某个索引的值 136 * @param int $index 数组索引值 137 * @return string 138 public function getCarsAt($index) { 139 return $this->get(self::CARS, $index); 140 } 141 142 /** 143 * 获得数组的数量 144 * @return int 145 */ 146 public function getCarsCount() { 147 return $this->count(self::CARS); 148 } 149 150 /** 151 * 获得数组的迭代类 152 * @return ArrayIterator 153 */ 154 public function getCarsIterator() { 155 return new ArrayIterator($this->get(self::CARS)); 156 } 157 158 }
使用姿势:
1 <?php 2 $person = new Person(); 3 $person->setName('Arno'); 4 $person->setAge(18); 5 $person->appendCars('宝马'); 6 $person->appendCars('奔驰'); 7 8 $packed = $person->serializeToString(); //序列化成proto格式 9 $cc = $person->getCarsCount(); 10 var_dump($cc); 11 #file_put_contents('person.proto', $packed); //保存成文件或mysql的二进制字段里 12 13 //以下为读过程 14 15 $person->reset(); 16 try { 17 $person->parseFromString($packed); 18 } catch ( Exception $e ) { 19 die('Upss.. there is a bug in this example'); 20 } 21 22 $person->dump(); //输出
4. 参考:
Google开发者官网: https://developers.google.com/protocol-buffers/
Google的Github官网: https://github.com/google/protobuf
PHP的Protobuf扩展官网: https://github.com/allegro/php-protobuf

浙公网安备 33010602011771号