当前位置: 首页 > 后端技术 > PHP

在php中使用protobuffer

时间:2023-03-29 22:05:23 PHP

ProtobufProtobuf(Protocolbuffers)简介是Google出品的一种跨平台、跨语言、可扩展的数据传输和存储协议,是高效的数据压缩编码方式之一。Protocolbuffers在序列化数据方面灵活高效。与XML相比,协议缓冲区更小、更快、更简单。一旦定义了待处理数据的数据结构,就可以使用Protocolbuffers的代码生成工具生成相关代码。甚至可以在不重新部署程序的情况下更新数据结构。使用Protobuf简单描述一次数据结构,轻松读写各种语言或各种数据流中的结构化数据。Protocolbuffers非常适合数据存储或RPC数据交换格式。一种与语言无关、平台无关、可扩展的序列化结构化数据格式,可用于通信协议、数据存储等领域。此外,Protobuf由于其在内网高效的数据交换效率,被广泛应用于微服务中。Google的开源框架grpc就是基于此构建的。php-protobuf安装由于protobuf本身不支持php,如果php使用pb,需要安装相应的扩展。peclinstallprotobuf环境需要protoc编译器,下载安装:2.5.0.tar.gz$cdprotobuf-2.5.0$./configure--prefix=/usr/local/protobuf$sudomake$sudomakeinstall验证安装是否成功:$/usr/local/protobuf/bin/protoc--versionlibprotoc2.5.0php-protobuf安装成功php--riprotobufinstalllumenandgoogle/protobufdependsonlumennewrpclumennewrpc命令相当于composercreate-projectlaravel/lumenrpccomposerrequiregoogle/protobufaddclassmapundercomposer.json:{"classmap":["protobuf/"]}ok,准备工作完成。自己做个demo在代码目录下创建protobuf文件夹mkdirprotobuf进入目录,创建文件searchRequest.protosyntax="proto3";messageSearchRequest{stringquery=1;int32page_number=2;int32result_per_page=3;枚举语料库{UNIVERSAL=0;网络=1;图像=2;本地=3;新闻=4;产品=5;视频=6;}语料库语料库=4;}?这重要吗?在composer.json下添加classmap,否则会检测不到对应的class{"classmap":["protobuf/"]}命令行运行:protoc--proto_path=protobuf/--php_out=protobuf/protobuf/searchRequest.proto&&composerdump-autoloadnow你看到的代码目录应该是这样的:至此,我们需要的request类已经获取到了,下面来看看如何使用吧!使用$router->get('testp','ExampleController@testProtobuf')在web.php中创建一个路由;在ExampleController下添加:publicfunctiontestProtobuf(){//require_oncebase_path('protobuf/SearchRequest.php');$request=new\SearchRequest();$request->setPageNumber(67);dd($request->getPageNumber());}如果正常打印数字67,这意味着可以使用该类。恭喜,您已经成功完成了请求类的创建。更深入现在,让我们看看生成的SearchRequest的方法:array:16[▼0=>"__construct"1=>"getQuery"2=>"setQuery"3=>"getPageNumber"4=>"setPageNumber"5=>"getResultPerPage"6=>"setResultPerPage"7=>"getCorpus"8=>"setCorpus"9=>"clear"10=>"discardUnknownFields"11=>"serializeToString"12=>"mergeFromString"13=>"serializeToJsonString"14=>"mergeFromJsonString"15=>"mergeFrom"]这里设置前缀的方法是设置对应的字段get的都是从缓冲区中获取值。对于里面的SerializeToString,建议阅读官方文档,里面有相应的合理解释。结合grpccomposerinstallgrpc/grpcdefinesService,这个需要在客户端和服务端完成服务RouteGuide{rpcGetFeature(Point)returns(Feature){}rpcRecordRoute(streamPoint)returns(RouteSummary){}rpcRouteChat(streamRouteNote)返回(streamRouteNote){}}messagePoint{int32latitude=1;int32longitude=2;}protoc生成对应的Service实例。创建一个客户端$client=newRouteguide\RouteGuideClient('localhost:50051',['credentials'=>Grpc\ChannelCredentials::createInsecure(),]);调用RPC服务$point=newRouteguide\Point();$point->setLatitude(409146138);$point->setLongitude(-746188906);list($feature,$status)=$client->GetFeature($point)->wait();grpc的更多实现,请参考官方文档,快速指南