You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP处理Protobuf响应调用mergeFromString报Unexpected wire type错误求助

问题原因
  • 核心原因是CURL配置项CURLOPT_HEADER设置为true,该配置会让curl_exec()返回的结果同时包含HTTP响应头+响应体两部分内容,而mergeFromString()方法要求传入的参数必须是纯Protobuf序列化后的二进制响应体,混入响应头后自然会触发解析格式错误。
  • 你打印出的$curlResponse开头有乱码字符,就是HTTP响应头的二进制内容被当成字符串输出的表现,和你预期的纯Protobuf结构不符。
  • 补充说明:你在proto文件中只定义了编号为2的字段不属于错误原因,Protobuf本身兼容忽略未定义的字段,这也是Protoman用相同proto可以正常解析的原因(Protoman会自动剥离HTTP响应头,只拿响应体做Protobuf解析)。
解决方法

方案1:直接修改CURL配置(推荐)

将CURLOPT_HEADER改为false,这样curl_exec()只会返回纯响应体内容,直接传入mergeFromString()即可正常解析:

$handle = curl_init($url);

$curl_options = [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => $body,
    CURLOPT_HEADER => false, // 修改该配置项即可
    CURLOPT_VERBOSE => true
];

curl_setopt_array($handle, $curl_options);

$curlResponse = curl_exec($handle);

$responseMessage = new MyMessage();
$responseMessage->mergeFromString($curlResponse);

curl_close($handle);

方案2:手动拆分响应头和响应体

如果你确实需要保留响应头用于其他逻辑,可以利用HTTP协议中响应头和响应体用\r\n\r\n分隔的规则手动拆分,取后半部分的响应体做解析即可:

$curlResponse = curl_exec($handle);
// 拆分响应头和响应体,最多拆分2段避免响应体中出现分隔符被误拆分
list($headerContent, $responseBody) = explode("\r\n\r\n", $curlResponse, 2);

$responseMessage = new MyMessage();
$responseMessage->mergeFromString($responseBody);

curl_close($handle);

内容的提问来源于stack exchange,提问作者eniel.rod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 08:24:05