目前有个项目使用yii2.0+protobuf3.0进行开发,如何能让protoc生成的类文件能自动加载呢。
step1. 编写 proto 文件:
$ cd web-server
$ mkdir Proto
$ cd Proto
$ vim usersvr.proto
syntax = "proto3";
package proto.message.usersvr; // protoc 自动生成 Proto/Message/Usersvr 目录,目录首字母大写
// 获取用户信息
message GetUserInfo {
int32 errcode = 1;
string errmsg = 2;
}
step2. 生成 protobuf php 文件
$ cd web-server/Proto
$ protoc --php_out=../ user.proto
这样在项目的根目录 web-server 下就生成了 GPBMetadata 和 Proto/Message/Usersvr 两个目录,而且这两个目录里的文件的 namespace 和目录结构都是一一对应的,分别是:namespace GPBMetadata; 和 namespace Proto\Message\Usersvr;,php 的 namespace 和目录结构不需要一致,不过最好保持一致。
step3. 自动引入刚刚生成的 protobuf php 文件
因为我是模块化开发,新建了 usersvr 模块,所以可以在 modules/usersvr/Modules.php 文件里加上 autoload 自动引用刚刚生成的 protobuf php 文件,这样 usersvr 模块下的所有文件就不用手动去引用这些文件了,直接使用就可以了:
$ vim web-server/modules/usersvr/Module.php // 模块文件
namespace app\modules\usersvr;
// 引入常量文件
require_once __DIR__ . '/../../constants/constant.php';
// 自动引入proto文件
spl_autoload_register(function ($className) {
if(strpos($className, 'Proto') !== false || strpos($className, 'GPBMetadata') !== false) { // Proto或GPBMetadata开头
$className = str_replace("\\","/", $className);
require_once __DIR__ . '/../../'.$className.'.php';
}
});
class Module extends \yii\base\Module
{
public function init()
{
parent::init();
}
}
step4. 开始使用刚刚生成的 protobuf php 文件
自动引入以后,在 modules/usersvr/controllers 里就可以使用 protobuf php 文件里的类了:
$ vim web-server/modules/usersvr/controllers/UserController.php
namespace app\modules\usersvr\controllers;
// 获取用户信息
public function actionGetuserinfo()
{
// 调用 protobuf php 文件里的类 GetUserInfo
$msg = new \Proto\Message\Usersvr\GetUserInfo(); // namespace 和文件所在目录结构是一致的
$msg->setErrcode(500); // 设置 errcode
$msg->setErrmsg('没有数据'); // 设置 errmsg
// 输出
echo $msg->serializeToString();
return;
}