搜了一遍,好像对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 <?php2 /**3 * 人4 * 声明一个ProtobufMessage的子类5 * 要实现ProtobufMessage里的抽象方法reset6 *7 */
8 class Person extendsProtobufMessage{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 functionfields() {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 string65 */
66 public functiongetName() {67 return $this->get(self::NAME);68 }69
70 /**71 * 设置名字72 * @param string $name73 * @return bool74 */
75 public function setName($name) {76 return $this->set(self::NAME, $name);77 }78
79 /**80 * 获得年龄81 * @return int82 */
83 public functiongetAge() {84 return $this->get(self::AGE);85 }86
87 /**88 * 设置年龄89 * @param int $age90 * @return bool91 */
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 $car112 * @return bool113 */
114 public function appendCars($car) {115 return $this->append(self::CARS, $car);116 }117
118 /**119 * 清除值120 * @return bool121 */
122 public functionclearCars() {123 return $this->clear(self::CARS);124 }125
126 /**127 * 获得值128 * @return array129 */
130 public functiongetCars() {131 return $this->get(self::CARS);132 }133
134 /**135 * 获得某个索引的值136 * @param int $index 数组索引值137 * @return string138 public function getCarsAt($index) {139 return $this->get(self::CARS, $index);140 }141
142 /**143 * 获得数组的数量144 * @return int145 */
146 public functiongetCarsCount() {147 return $this->count(self::CARS);148 }149
150 /**151 * 获得数组的迭代类152 * @return ArrayIterator153 */
154 public functiongetCarsIterator() {155 return new ArrayIterator($this->get(self::CARS));156 }157
158 }
使用姿势:
1 <?php2 $person = newPerson();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