一.摘要
和上一文差不多,只是php的protobuf扩展用第三方实现了,看起来更简单更方便使用protobuf.
二.安装protoc编译器
和上文一样.
三.安装php扩展
cd /data
git clone https://github.com/allegro/php-protobuf
cd php-protobuf
git checkout -b php5 origin/php5
/usr/local/php/bin/phpize
./configure && make && sudo make install
php.ini文件: extension=protobuf.so
php -m |grep protobuf
composer install
四.使用protobuf
1.协议文件编写
./proto/person.proto
syntax = "proto3";
package Playwhale;
message Person{
string name = 1;
int32 age = 2;
string email = 3;
enum PhoneType{
HOME = 0;
MOBILE = 1;
WORK = 2;
}
message Phone{
int64 id = 1;
PhoneType type = 2;
}
repeated Phone phoneNum = 4;
}
message UserList{
string name = 1;
repeated Person users = 2;
}
2.编译协议文件
php /data/php-protobuf/protoc-gen-php.php -o ./pb ./proto/person.proto
如果用protobuf编译时报错:protoc: error while loading shared libraries: libprotoc.so.9: cannot open shared obje:
文件:/etc/bash.bashrc,
添加一行代码: export LD_LIBRARY_PATH=/usr/local/lib
3.测试
a.测试文件: ./tests/meng.php
<?php /** * Created by PhpStorm. * User: meng * Date: 18-10-17 * Time: 下午3:26 */ $start_time = microtime(true); $start_mem = memory_get_usage(); include '../Autoloader.php'; use Playwhale\Person; $from = new \Playwhale\Person(); $from->setName('jack'); $from->setAge(100); $from->setEmail('foo bar, this is a message'); //phone $phones = array(); $phone_obj = new \Playwhale\Person_Phone(); $phone_obj->setId(10000); $phone_obj->setType(\Playwhale\Person_PhoneType::HOME); $from->appendPhoneNum($phone_obj); $phone_obj = new \Playwhale\Person_Phone(); $phone_obj->setId(50000); $phone_obj->setType(\Playwhale\Person_PhoneType::WORK); $from->appendPhoneNum($phone_obj); //$encode_data = $from->serializeToString(); $encode_data = $from->serializeToString(); printf("encode_data=%s\n", $encode_data); printf("from: phoneNum=%s\n", json_encode($from->getPhoneNum())); file_put_contents('data.bin', $encode_data); echo "\n"; echo "\n"; $to = new \Playwhale\Person(); $to->parseFromString($encode_data); printf("name=%s\n", $to->getName()); printf("age=%s\n", $to->getAge()); printf("email=%s\n", $to->getEmail()); $count = $to->getPhoneNumCount(); /* foreach ($to->getPhoneNum() as $tmp_phone_obj) { printf("phone: id=%s, type=%s\n", $tmp_phone_obj->getId(), $tmp_phone_obj->getType()); } */ /* for ($i = 0; $i < $count; ++$i) { $tmp_phone_obj = $to->getPhoneNumAt($i); printf("phone: id=%s, type=%s\n", $tmp_phone_obj->getId(), $tmp_phone_obj->getType()); } */ /**@var \ArrayIterator $iterator*/ $iterator = $to->getPhoneNumIterator(); while ($iterator->valid()) { $tmp_phone_obj = $iterator->current(); printf("phone: id=%s, type=%s\n", $tmp_phone_obj->getId(), $tmp_phone_obj->getType()); $iterator->next(); } echo "\n"; echo "\n"; $end_time = microtime(true); $end_mem = memory_get_usage(); $mem = ($end_mem - $start_mem) / 1024 / 1024; printf("\nlast seconds=%ss, lost_mem=%sm ok.\n", $end_time-$start_time, $mem);
b.Autoloader.php
<?php
class Autoloader
{
/**
* Load files by namespace.
*
* @param string $name
* @return boolean
*/
public static function loadByNamespace($name)
{
$class_path = str_replace('\\', DIRECTORY_SEPARATOR, $name);
if (strpos($name, 'Playwhale\\') === 0) {
$class_file = __DIR__. '/pb/'. $class_path . '.php';
}
if (is_file($class_file)) {
include_once($class_file);
if (class_exists($name, false)) {
return true;
}
}
return false;
}
}
spl_autoload_register('Autoloader::loadByNamespace');
c.测试
/usr/local/bin/php -dxdebug.remote_enable=1 -dxdebug.remote_mode=req -dxdebug.remote_port=9000 -dxdebug.remote_host=127.0.0.1 ./tests/meng.php
d.测试结果
last seconds=0.0011978149414062s, lost_mem=0.0703125m ok.
last seconds=0.0010819435119629s, lost_mem=0.0703125m ok.
last seconds=0.0011160373687744s, lost_mem=0.0703125m ok.
五.总结
allegro/php-protobuf,这个php扩展使用起来就是好!