文章目录

  • protobuf
  • 扩展安装
  • 安装protoc
  • 代码测试
  • thinkPHP中使用protobuf

protobuf

protobuf是一个通信协议,类似json和xml。protobuf反序列化之后体积比他们小,而且序列化和反序列化的性能要比他们高(json不一定 如果protobuf层级太多不一定比json快,一般1-3个层级的情况下几乎都是protobuf比较快)

扩展安装

github地址:

https://github.com/allegro/php-protobuf/

切换到root用户

git clone https://github.com/allegro/php-protobuf

进入php-protobuf目录

cd php-protobuf

安装扩展库

phpize
./configure
make
make install

检查protobuf库是否被安装到扩展目录下

php -i| grep extension_dir

输出扩展目录

extension_dir => /usr/lib64/php/modules => /usr/lib64/php/modules

ll /usr/lib64/php/modules

确认是否有 protobuf.so

-rwxr-xr-x 1 root root  159704 Nov 23 11:15 protobuf.so

如果找不到 make的时候会提示库被安装到哪里了

libtool: install: cp ./.libs/protobuf.so /usr/local/src/php-protobuf/modules/protobuf.so

/bin/sh /usr/local/src/php-protobuf/libtool --mode=install cp ./protobuf.la /usr/local/src/php-protobuf/modules
libtool: install: cp ./.libs/protobuf.so /usr/local/src/php-protobuf/modules/protobuf.so
libtool: install: cp ./.libs/protobuf.lai /usr/local/src/php-protobuf/modules/protobuf.la
libtool: finish: PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/mysql/bin/:/usr/local/go/bin:/root/bin:/sbin" ldconfig -n /usr/local/src/php-protobuf/modules
----------------------------------------------------------------------
Libraries have been installed in:/usr/local/src/php-protobuf/modulesIf you ever happen to want to link against installed libraries
in a given directory, LIBDIR, you must either use libtool, and
specify the full pathname of the library, or use the `-LLIBDIR'
flag during linking and do at least one of the following:- add LIBDIR to the `LD_LIBRARY_PATH' environment variableduring execution- add LIBDIR to the `LD_RUN_PATH' environment variableduring linking- use the `-Wl,-rpath -Wl,LIBDIR' linker flag- have your system administrator add LIBDIR to `/etc/ld.so.conf'See any operating system documentation about shared libraries for
more information, such as the ld(1) and ld.so(8) manual pages.
----------------------------------------------------------------------Build complete.
Don't forget to run 'make test'.

修改配置文件
配置有两种方式 一种是创建 protobuf.ini 文件,一种是接在在 php.ini中修改,这里用第一种

vim /etc/php.d/protobuf.ini

; Enable protobuf extension module
extension=protobuf.so

如果修改 php.ini,添加如下配置

extension=protobuf.so

确认扩展是否安装成功

php -m | grep -i protobuf

输入 protobuf 则说明安装成功

protobuf

安装protoc

protoc是专门用来生成对应语言的代码文件的工具
可以直接在github的release列表上下载,

wget https://github.com/protocolbuffers/protobuf/releases/download/v3.11.0-rc2/protoc-3.11.0-rc-2-linux-x86_64.zip
unzip protoc-3.11.0-rc-2-linux-x86_64.zip
cp -rf ./bin ./include /usr/local

代码测试

命令

protoc -I=./proto/ --php_out=./protobuf ./proto/*

参数解释
-I : 包含的库文件目录
–php_out : 输出php文件
最后一个参数 : 需要编译的proto文件

创建两个目录

mkdir proto
mkdir protbuf

写一个proto文件

vim ./proto/foo.proto

syntax = "proto3";message Foo
{int32 bar = 1;string baz = 2;float spam = 3;
}

生成php代码

protoc -I=./proto/ --php_out=./protobuf ./proto/*

执行之后目录下文件如下:

|-- proto
|   `-- foo.proto
`-- protobuf|-- Foo.php`-- GPBMetadata`-- Foo.php

开发时候使用的是

./protobuf/Foo.php

里面有各个字段的get/set方法和序列化反序列化方法

GPMMetadata下的Foo.php文件则是记录,各个字段所在位置的信息

使用 Foo.php
新建一个test.php

<?php
require_once './vendor/autoload.php';
require_once './protobuf/Foo.php';
require_once 'protobuf/GPBMetadata/Foo.php';$foo = new Foo();
$foo->setBar(1);
$foo->setBaz('tow');
$foo->setSpam(3.300); $packed = $foo->serializeToString();$parsedFoo = new Foo();
$parsedFoo->mergeFromString($packed);
var_dump($parsedFoo->getBaz());
var_dump($parsedFoo->getBar());
var_dump($parsedFoo->getSpam());

这时还没有引入protobuf库的相关代码,运行的时候回报错一些类没有找到例如:

PHP Fatal error: Class ‘Google\Protobuf\Internal\Message’ not found

运行:

composer require google/protobuf

安装 protobuf库 ,然后再执行 php test.php,输出如下内容说明可以正常使用protobuf了

string(3) "tow"
int(1)
float(3.2999999523163)

thinkPHP中使用protobuf

安装bcmatch
在thinkphp中跑的时候遇到了一个问题

Error: php70w-common conflicts with php-common-5.4.16-46.1.el7_7.x86_64

所以安装了7.0.33版本的bcmatch

yum install php70w-bcmath

查了几个文档,thinkphp引入第三方库的时候,都要几行代码 vender(xx) , 同时pb生成的文件也没有按照thinkphp的文件名称规则上传,不是xxx.class.php,估计自动加载的时候就不行了。想想还是自己写一下自动加载的方法。

在applaction目录下增加三个目录


library   //放protobuf运行时运加载的类文件,vendor里面下载的 src 部分的文件|-Google|-GPBMetadata|-phpdoc.list.xml
protocols //通过protoc 生成的php代码文件|-GPBMetadata|-Protocols
protofile|-common //一些公共文件,foo.proto里面就import了 header.proto文件|-header.proto|-protos|-foo.proto

在protofile目录下执行 生成PB文件命令

protoc -I=./proto/ -I./common/ --php_out=./protobuf ./proto/* ./common/*

在protocols目录下就会生成对应的proto文件

foo.protoc

syntax = "proto3";
import "header.proto";
package protocols;
message Foo
{Header head = 1;int32 bar = 2;string baz = 3;float spam = 4;
}

header.protoc

syntax = "proto3";
package protocols;
message Header
{uint32 cmd = 1;string deviceToken = 2;string authCode = 3;
}

修改index.php
增加一个函数


function autoload($path){spl_autoload_register(function($className)use($path){$className = ltrim($className, '\\');$path = rtrim($path, '/');if ($lastNsPos = strripos($className, '\\')) {$namespace = substr($className, 0, $lastNsPos);$className = substr($className, $lastNsPos + 1);$fileName = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;$basePath = stristr($namespace, '\\', true);if(false === $basePath){$basePath = $namespace;}if(strlen($path) >= strlen($basePath) && (0 === substr_compare($path, $basePath, strlen($basePath)*-1))) {$fileName = __DIR__ . DIRECTORY_SEPARATOR . $fileName . $className . '.php';}else{$fileName = $path .DIRECTORY_SEPARATOR. $fileName . $className . '.php';}}else{$fileName = $path .DIRECTORY_SEPARATOR. $className  . '.php';}if (file_exists($fileName)) {require $fileName;return true;}return false;});
}

在 define(‘APP_DEBUG’) 后添加两行代码

autoload('./library');
autoload('./protocols');

代码测试
在一个controller 中增加一个接口

    public function testPb() {$foo = new Foo();$foo->setBaz("hahah");$foo->setBar(10);$foo->setSpam(3.245);$header = new Header();$header->setAuthCode("fdsfds");$header->setCmd(12);$foo->setHead($header);$str = $foo->serializeToJsonString();var_dump($str);$parsedFoo = new Foo();try {$parsedFoo->mergeFromJsonString($str);}   catch (\Exception $e) {echo "????\n";}var_dump($parsedFoo->getBar());var_dump($parsedFoo->getBaz());var_dump($parsedFoo->getSpam());var_dump($parsedFoo->getHead()->getAuthCode());var_dump($parsedFoo->getHead()->getCmd());echo "ok!\n";}

用一个工具来测试,我这里用的是postman
发了请求之后输出

string(75) "{"head":{"cmd":12,"authCode":"fdsfds"},"bar":10,"baz":"hahah","spam":3.245}"
int(10)
string(5) "hahah"
float(3.245)
string(6) "fdsfds"
int(12)
ok!

ok说明安装成功

php安装protocol buffer 扩展,thinkphp引入protocol buffer相关推荐

  1. nginx 支持php扩展,Nginx和php安装及配置五之LINUX用PHPIZE安装PHP GD扩展

    篇文章给大家分享的内容是关于Nginx和php安装及配置五之LINUX用PHPIZE安装PHP GD扩展,有着一定的参考价值,有需要的朋友可以参考一下 1.生成so文件 [1]sudo yum ins ...

  2. linux php7扩展查看,linux安装PHP7以及扩展

    Linux下安装PHP7 事先升级gcc4.8,然后安装PHP7,安装步骤参考:CentOS安装PHP7 1.Linux下编译的php没有php.ini 解决办法:从源代码目录中复制php.ini-d ...

  3. Linux下安装Redis php-redis扩展 redis重启shell脚本 超详细!

    前言 前面刚写过nosql其中三款热门产品的对比,这次主要写关于Redis的一些事情,Redis的介绍.安装以及扩展(php-redis,因为我是phper)安装等等.同时是写给我的朋友(cccjjj ...

  4. 此问题可能是由配置更改或安装另一个扩展导致的

    未能正确加载"Microsoft.VisualStudio.Editor.Implementation.EditorPackage, Microsoft.VisualStudio.Edito ...

  5. 【Groovy】Groovy 扩展方法 ( Groovy 扩展方法引入 | 分析 Groovy 中 Thread 类的 start 扩展方法 )

    文章目录 一.Groovy 扩展方法引入 二. 分析 Groovy 中 Thread 类的 start 扩展方法 一.Groovy 扩展方法引入 Groovy 可以对 JDK 中的一些类进行 方法扩展 ...

  6. Windows下Memcache的安装及PHP扩展配置方法

    这篇文章主要介绍了Windows下Memcache的安装及PHP扩展配置方法,需要的朋友可以参考下 一.下载 找到完整的memcache的Windows安装包,解压放在硬盘上,比如 F:\memcac ...

  7. python3.7扩展库是什么_Python3.4以后的版本中,____________库用于安装管理Python扩展包,________________库用于发布Python包。_学小易找答案...

    [填空题]Python3.4以后的版本中,____________库用于安装管理Python扩展包,________________库用于发布Python包. [判断题]Directions: The ...

  8. deb php7 fileinfo,linux安装php7.2扩展fileinfo

    最简便的方法是使用pecl安装php的扩展,方便快捷,这里使用的是源码编译安装php扩展 项目 中上传图片遇到的问题: 明显是fileinfo不被支持,没有安装fileinfo.接下来开始安装 因为我 ...

  9. php-5.2.6安装,php5.2.6安装openssl.o扩展,make时报错?

    问题: 调试支付宝支付时报错:Fatal error: Call to undefined function openssl_get_privatekey()` 在网上查了 说是没有安装openssl ...

最新文章

  1. ORACLE JET BASIC TABLE
  2. Java设计模式之适配器模式
  3. linux date 小写h,linux date 命令详解[转载]
  4. duilib学习领悟(4)
  5. PhpStorm failed to transfer files by FTP 报错解决方法
  6. linux core文件乱码,.net core在linux下图片中文乱码
  7. 南京oracle soa,Oracle SOA平台之甲骨文SOA套件概述
  8. 演示如何利用log4net记录程序日志信息
  9. 去银行写代码是种什么体验?
  10. oracle返回当前日期函数,oracle 日期时间函数使用总结
  11. pandas操作手册
  12. 工程项目进度控制的主要措施有哪些?
  13. 基于微信小程序的培训机构系统
  14. MacBook Pro外接键盘中的shift键失效问题
  15. NW.js之基础篇(2)
  16. c++primer第十六章模板特例化
  17. STM32入门笔记——PWM
  18. matlab批量将图片处理为灰度图
  19. swust oj 996 打印杨辉三角形
  20. 齐夫定律, Zipf's law,Zipfian distribution

热门文章

  1. 翌加:抖音账号被限流了如何解决
  2. 关于《数据仓库知识体系》的超全指南(建议收藏)
  3. Unity粒子系统参数解析(一)
  4. 调试大普RTC芯片驱动-ins5699s
  5. Python随机生成一注双色球彩票
  6. 银河麒麟V10(飞腾2000+ ARM)环境下构建达梦V8数据库容器镜像
  7. html表达式 %3c,避开XSS过滤常用方法
  8. EditPlus中文版+英文版+注册码下载
  9. 仿淘宝淘抢购进度条——鸿洋
  10. Linux alias(别名)设置