refer: PHP讀寫protobuf3示例
一.環境
PHP 5.6.30 Ubuntu 16.04 LTSphp
二.安裝protobuf編譯器
cd /data/
git clone https://github.com/google/protobuf.gitgit
cd protobuf
sudo apt-get install autoconf automake libtool curl make g++ unzipgithub
./autogen.sh
./configurejson
make
sudo make install
sudo ldconfig # refresh shared library cache.bash
三.安裝php擴展
cd /data/protobuf/php/ext
/usr/local/php/bin/phpize
curl
./configure && make && sudo make install
php.ini文件: extension=protobuf.so
php -m |grep protobuf
四.使用protobuf
To use PHP runtime library requires:性能
1.協議文件編寫
/data/protobuf/php/tests/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.編譯協議文件
protoc --proto_path=/data/protobuf/php/tests/proto/ --php_out=/data/protobuf/php/tests/pb /data/protobuf/php/tests/proto/person.protoui
3.測試
a.測試文件: /data/protobuf/php/tests/meng.php this
<?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); $phones[] = $phone_obj; $phone_obj = new \Playwhale\Person\Phone(); $phone_obj->setId(30000); $phone_obj->setType(\Playwhale\Person\PhoneType::WORK); $phones[] = $phone_obj; $from->setPhoneNum($phones); //$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->mergeFromString($encode_data); printf("name=%s\n", $to->getName()); printf("age=%s\n", $to->getAge()); printf("email=%s\n", $to->getEmail()); foreach ($to->getPhoneNum() as $tmp_phone_obj) { printf("phone: id=%s, type=%s\n", $tmp_phone_obj->getId(), $tmp_phone_obj->getType()); } 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, 'Google\\') === 0 || strpos($name, 'GPBMetadata\\') === 0) { $class_file = __DIR__ . '/../src/'. $class_path. '.php'; //若是經過php擴展使用protobuf,則這裏的處理能夠忽略. } elseif (strpos($name, 'Playwhale\\') === 0) { $class_file = __DIR__. '/pb/'. $class_path . '.php'; } if (!is_file($class_file)) { if(strpos($name, 'GPBMetadata\\') === 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 /data/protobuf/php/tests/meng.php
d.測試結果
1).使用php擴展測試:
last seconds=0.0017640590667725s, lost_mem=0.069038391113281m ok.
last seconds=0.0021541118621826s, lost_mem=0.069038391113281m ok.
last seconds=0.0018389225006104s, lost_mem=0.069038391113281m ok.
2).使用php原生語言包測試:
last seconds=0.059786796569824s, lost_mem=1.9029998779297m ok.
last seconds=0.10011792182922s, lost_mem=1.9029998779297m ok.
last seconds=0.060681104660034s, lost_mem=1.9029998779297m ok.
last seconds=0.058160066604614s, lost_mem=1.9029998779297m ok.
3).使用php擴展有更好的性能表現,比另外一個使用方法提升20到30倍.
五.總結 1.編寫protobuf協議文件 2.使用protoc編譯協議文件,導出php語言支持的協議文件 3.使用php擴展或php原生包,解釋php協議文件 4.推薦使用php擴展解釋協議文件,有更好的性能表現.