«

Golang gRPC + PHP 客户端开发实战笔记

时间:2025-6-20 18:04     作者:wanzi     分类: php


📘 Go porject gRPC + PHP 客户端开发实战笔记

🧩 目标


🧱 一、环境准备

✅ 安装依赖(以 CentOS 为例)

sudo yum install -y git gcc-c++ make cmake unzip php php-cli php-devel php-pear
pecl install grpc
echo "extension=grpc.so" >> /etc/php.ini

✅ 安装 protoc

PROTO_VERSION=25.3
cd /usr/local/src
curl -OL https://github.com/protocolbuffers/protobuf/releases/download/v${PROTO_VERSION}/protoc-${PROTO_VERSION}-linux-x86_64.zip
unzip protoc-${PROTO_VERSION}-linux-x86_64.zip -d protoc-${PROTO_VERSION}
sudo cp -r protoc-${PROTO_VERSION}/bin/* /usr/local/bin/
sudo cp -r protoc-${PROTO_VERSION}/include/* /usr/local/include/
protoc --version  # 确认版本

🛠 二、编译 grpc_php_plugin

✅ 拉取 gRPC 源码

cd ~
git clone -b v1.58.0 https://github.com/grpc/grpc
cd grpc
git submodule update --init --recursive

✅ 编译插件

mkdir -p cmake/build
cd cmake/build
cmake ../.. -DgRPC_INSTALL=ON -DgRPC_BUILD_TESTS=OFF -DgRPC_BUILD_PHP_PLUGIN=ON
make grpc_php_plugin -j$(nproc)
sudo cp grpc_php_plugin /usr/local/bin/
grpc_php_plugin --version

📦 三、导出 Go project 的 proto 文件

✅ 拉取 proto 文件(只保留 .proto)

# save as download_Go_proto.py
import os, shutil
from git import Repo

target = os.path.join(os.getcwd(), 'Go_api')
if os.path.exists(target): shutil.rmtree(target)

Repo.clone_from('https://github.com/XTLS/Go-core.git', target)

for root, dirs, files in os.walk(target):
    for name in files:
        if not name.endswith('.proto'):
            os.remove(os.path.join(root, name))
pip install GitPython
python3 download_Go_proto.py

🧪 四、生成 PHP 客户端代码

✅ 生成脚本 generate_php_grpc.sh

#!/bin/bash
set -e

ROOT=$(pwd)
Go_API="$ROOT/Go_api"
OUT_DIR="$ROOT/dist/php"
PLUGIN="/usr/local/bin/grpc_php_plugin"

mkdir -p "$OUT_DIR"

PROTO_FILES=$(find "$Go_API" -name "*.proto")
PROTO_PATH="--proto_path=$Go_API"

protoc $PROTO_PATH \
  --php_out="$OUT_DIR" \
  --grpc_out="$OUT_DIR" \
  --plugin=protoc-gen-grpc="$PLUGIN" \
  $PROTO_FILES

echo "✅ 生成完成,输出目录: $OUT_DIR"
chmod +x generate_php_grpc.sh
./generate_php_grpc.sh

📁 五、集成到 PHP 项目

✅ 复制文件结构

dist/php/
├── xxx/
└── xxx/

放入你的项目目录,如:

my-php-project/
└── grpc_clients/
    ├── xxx/
    └── xxx/

✅ 配置 composer.json 自动加载

"autoload": {
  "psr-4": {
    "GPBMetadata\\": "grpc_clients/xxxx/",
    "Go\\": "grpc_clients/xxx/"
  }
}

然后执行:

composer dump-autoload

✅ 示例调用

use Go\Core\HandlerServiceClient;
use Grpc\ChannelCredentials;

$client = new HandlerServiceClient('127.0.0.1:10085', [
    'credentials' => ChannelCredentials::createInsecure(),
]);

// 示例调用(AddInbound)
// $request = new Go\Core\AddInboundRequest();
// $request->set...()
// list($response, $status) = $client->AddInbound($request)->wait();

🔧 编码注意事项

问题 原因 解决方案
GPBMetadata 中有乱码 插入了二进制 descriptor 正常,不要修改
文件编码报错 BOM 或非 UTF-8 sed/iconv 去 BOM
PHP 扩展未加载 grpc.so 未启用 echo "extension=grpc.so" >> php.ini

✅ 总结

步骤 工具
安装工具 protoc, grpc_php_plugin, grpc.so
拉取 proto GitPython
批量生成 generate_php_grpc.sh
集成到 PHP 项目 composer + PSR-4
调用 gRPC Go\ServiceClient + wait()