php安装protocol buffer 扩展,thinkphp引入protocol buffer

6 篇文章 0 订阅

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/modules

If 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 variable
     during execution
   - add LIBDIR to the `LD_RUN_PATH' environment variable
     during 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说明安装成功

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
thinkphp是一个使用PHP语言编写的开源框架,旨在为开发人员提供便捷的开发方式和高效的开发体验。而dompdf是一个用于将HTML文档转换为PDF格式的PHP库。 在thinkphp引入dompdf需要经过以下步骤: 1. 下载dompdf库:首先需要在dompdf的官方网站或者开源代码托管平台上下载dompdf的最新版本。通常来说,dompdf会以一个压缩文件的形式提供下载。 2. 解压缩:将下载得到的压缩文件解压缩到thinkphp项目的合适目录下,可以将dompdf放置在thinkphp的vendor目录中。 3. 引入dompdf:在thinkphp项目中,打开config目录下的config.php或者其他合适的配置文件。在文件中加入下面的代码片段: ```php // 引入dompdf的自动加载文件 require_once APP_PATH . 'vendor/dompdf/autoload.inc.php'; ``` 在此代码中,`APP_PATH`是thinkphp框架中存放应用代码的目录,根据实际情况修改路径。 4. 使用dompdf:在需要使用dompdf的代码文件中,使用`use`关键字引入dompdf的相关命名空间,并使用dompdf提供的类和方法完成对HTML文档转换为PDF格式的操作。例如: ```php use Dompdf\Dompdf; // 创建PDF对象 $dompdf = new Dompdf(); // 将HTML内容装载到PDF对象中 $dompdf->loadHtml('<h1>Hello, Dompdf!</h1>'); // 渲染PDF $dompdf->render(); // 输出PDF $dompdf->stream(); ``` 在上述示例代码中,首先通过`use`关键字引入了dompdf库的命名空间。然后,创建一个Dompdf对象,并使用`loadHtml`方法加载HTML内容。接着,使用`render`方法将HTML渲染为PDF,最后使用`stream`方法输出PDF内容。 综上所述,通过以上步骤,我们可以在thinkphp项目中成功引入dompdf库,并使用其功能进行HTML文档到PDF格式的转换。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值