赤练蛇牛 發表於 2019-9-6 16:56:00

php使用protobuf3

<p>简介:Google Protocol Buffer(简称Protobuf)是google公司内部的混合语言数据标准,目前已经正在使用的有超过48,162种报文格式定义和超过12183个.proto文件。他们用于RPC系统和持续数据存储系统。</p>
<p>Protocol Buffers是一种轻便高效的结构化数据存储格式,可以用于结构化数据串行化,或者说序列化。他很适合做数据存储或RPC数据交换格式。可用于通讯协议,数据存储等领域的语言无关、平台无关、可扩展的序列化结构格式</p>
<p>安装protobuf</p>
<p>进入网址:https://github.com/protocolbuffers/protobuf/releases/download/v3.9.1/protobuf-php-3.9.1.tar.gz</p>
<p>下载对应自己需要的安装包。进行安装</p>
<p>&nbsp; &nbsp; &nbsp;进入解压的安装包,执行一下命令</p>
<p>&nbsp; &nbsp; &nbsp;./configure</p>
<p>&nbsp; &nbsp; &nbsp;make &amp; make install&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp;export PATH = /usr/local/protobuf/bin:$PATH</p>
<p>&nbsp; &nbsp; &nbsp;protoc&nbsp; --version&nbsp; //查看是否安装成功</p>
<p>定义proto文件</p>
<p>例如:hello.proto</p>
<p>&nbsp; &nbsp; &nbsp; syntax = 'proto3';</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp;package lm;</p>
<p>&nbsp; &nbsp; &nbsp; message helloworld{</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int32 id = 1 ;&nbsp;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;string&nbsp; str = 2;</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;int32 opt = 3</p>
<p>&nbsp; &nbsp; &nbsp; }</p>
<p>&nbsp; &nbsp; &nbsp; 注意这里采用的是proto3的语法,和proto2不太一样,required和optional的限定已经没有了,所有字段都是可选的</p>
<p>&nbsp; &nbsp; 编译生成php文件</p>
<p>&nbsp; &nbsp; &nbsp;使用上面安装成功的protobuf进行编译proto文件</p>
<p>&nbsp; &nbsp; &nbsp;protoc hello.proto &nbsp;--php-out=./</p>
<p>&nbsp; &nbsp; &nbsp; 解释: --php_out :编译输出成php文件</p>
<p>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; --python_out :&nbsp;编译输出成python文件</p>
<p>&nbsp; &nbsp;</p>
<p>&nbsp;这时会在当前目录下,生成一个GPBMetadata的文件夹和LM的文件夹,此时查看lm文件夹下的helloword.php发现它&nbsp;use了Google\Protobug下的类,这时一个php库,可以去下载</p>
<p>&nbsp; &nbsp; &nbsp; composer require google/protobuf</p>
<p>&nbsp;使用composer引入google/protobuf后,项目种会出现一个vendor目录。在自己的代码中include vendor下的autoload.php,以及刚才生成的helloword.php文件,就可以进行二进制的读写了。</p>
<p>测试二进制读写</p>
<p>写入二进制文件</p>
<p>&nbsp; &nbsp;&nbsp;</p>
<pre>include_once "vendor/autoload.php";<br>include_once "GPBMetadata/hello.php";<br>include_once "Lm/hellword.php";<br><br>$from = new \Lm\helloword();<br>$from-&gt;setId(1);<br>$from-&gt;setOpt(29);<br>$from-&gt;setStr("foo bar, this is a message");<br>$data = $from-&gt;serializeToString();<br>file_put_contents("data.ini",$data);<br><br><br>读取二进制文件</pre>
<pre>include_once "vendor/autoload.php";<br>include_once "GPBMetadata/hello.php";<br>include_once "Lm/helloword.php";<br><br>$data = file_get_contents("data.bin");<br>$to = new \Lm\helloword();<br>$to-&gt;mergeFromString($data);<br>echo $to-&gt;getId().PHP_EOL;<br>echo $to-&gt;getOpt().PHP_EOL;<br>echo $to-&gt;getStr().PHP_EOL;<br><br>protobuf是什么,这么来的<br>简单来说就是干和xml一样的事,把某种数据结构的信息,以某种格式保存起来。主要用于数据存储、传输协议格式等场合。<br>专业的解答:protocol Buffers是一种轻便高效的结构化数据存储格式,可用于结构化数据串行化,很适合做数据存储或RPC数据交换格式。他可用于通讯协议、数据存储等领域的语言无关、平台无关<br>可扩展的序列化结构数据格式。<br><br>有了xml还搞protobuf原因:<br>根本原因还是:xml性能不好<br>1,时间维度:xml格式化(序列化)的开销倒还好;但是xml解析(反序列化)的开销就大了<br>2,空间维度:xml格式为了有较好的可读性,引入一些冗余的文本信息,所以空间开销也不是太好。<br><br>protobuf有什么好处?<br>1,对于数据结构的序列化反序列化等性能均优于xml<br>2,代码生成机制,使用起来十分方便<br>3,明星项目有使用:据了解google、新浪、美拍等均有用到protobuf,所以搬到项目肯定不会错<br><br>一,安装php的protobug扩展<br><br>wgethttps:<span class="hljs-comment">//github.com/allegro/php-protobuf/archive/master.zip<br></span><span class="hljs-comment">unzip master.zip<br>cd php-protobuf-master<br>yum install php-devel(安装依赖包)<br>phpize<br>./config --with-php -config=/usr/local/php/bin/php -config<br>make &amp;&amp; make install<br>//然后在php.ini 里面加一下extension = 'protobuf.so',再重启php与nginx即可<br><br>1,代码生成机制:生成proto文件<br>vim cbstest.proto<br><br>message Person{<br>    required string name =1 ;<br>    required int32 id =2;<br>    optional string email = 3;<br>    optional double money = 4;<br>}<br>然后执行 <br>php ./php-protobuf-master/protoc-gen-php.php cbstest.proto<br>然后就会形成一个Person.php的文件<br></span></pre>
<p>&lt;?php<br>/**<br> * Auto generated from cbstest.proto&nbsp;<br> */<br> <br>namespace {<br>/**<br> * Person message<br> */<br>class Person extends \ProtobufMessage<br>{<br>    /* Field index constants */<br>    const NAME = 1;<br>    const ID = 2;<br>    const EMAIL = 3;<br>    const MONEY = 4;<br> <br>    /* @var array Field descriptors */<br>    protected static $fields = array(<br>      self::NAME =&gt; array(<br>            'name' =&gt; 'name',<br>            'required' =&gt; true,<br>            'type' =&gt; \ProtobufMessage::PB_TYPE_STRING,<br>      ),<br>...省略...<br>}</p>
<pre>这里会集成ProtobufMessage类,他是在protobuf.so种自动加载的<br>php实战的用法<br>对于俺这样非大神的人还是更关注实际的用法,如下<br><br>$foo = new Person();<br>$foo-&gt;setName("helloproto");<br>$foo-&gt;setId(2);<br>$foo-&gt;setEmail('helloproto@mail.com');<br>$foo-&gt;setMoney(12323.763);<br>$packed = $foo-&gt;serializeToString();</pre>
<p>&nbsp;</p>
<pre>以上packed就是序列化后的结果,可直接存于数据库中<br><br>$p = new Person();<br>$p-&gt;parseFromString($packed);<br>echo $p-&gt;getName();<br>echo $p-&gt;getEmail();<br>echo $p-&gt;getMoney();<br>echo $p-&gt;getId();<br><br>以上用于数据的反序列化。</pre>
<p>&nbsp;</p><br><br>
来源:https://www.cnblogs.com/shangfz/p/11475810.html
頁: [1]
查看完整版本: php使用protobuf3