PHP 中的 protobuf 响应错误 "Unexpected wire type"
Error "Unexpected wire type" in a protobuf response in PHP
我正在执行对服务器的 POST 请求,服务器响应“正确”,但是当尝试调用 mergeFromString()
函数时,我收到以下错误:
Google\Protobuf\Internal\GPBDecodeException: Error occurred during parsing: Unexpected wire type. in Google\Protobuf\Internal\Message.php on line 353
我正在使用 CURL PHP:
$handle = curl_init($url);
$curl_options = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HEADER => true,
CURLOPT_VERBOSE => true
];
curl_setopt_array($handle, $curl_options);
$curlResponse = curl_exec($handle);
$responseMessage = new MyMessage();
$responseMessage->mergeFromString($curlResponse);
curl_close($handle);
var_dump($curlResponse)
结果如下:
╔╔eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjI1MTQwMTAsInVzZXJuYW1lIjoiNTM1MTAyODA2MCIsInZlcnNpb24iOiIyMTgwNiJ9.Li-bp3bIPdIrsRhuTWEWToS0ds62VCG-a2PCGaKSrigڲօ═"
在纯文本中,它应该看起来像这样:
1: 1
2: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjI1MTQwMTAsInVzZXJuYW1lIjoiNTM1MTAyODA2MCIsInZlcnNpb24iOiIyMTgwNiJ9.Li-bp3bIPdIrsRhuTWEWToS0ds62VCG-a2PCGaKSrig
3: 1619765852
我的响应.proto文件如下:
message MyMessage{
// I'm only interested in property 2
string prop = 2;
}
环境:
"protobuf-php / protobuf": "^ 0.1.3",
"google / protobuf": "^ 3.16"
但是,使用 Protoman (A Postman-like API client for protobuf-based messages) 的测试是成功的。我使用在 PHP.
中使用的相同原型文件进行了测试
在这种情况下,错误是因为字符串无效。
并且它是无效的,因为 CURL 返回的值(字符串)包括来自 HTTP 请求的所有数据,例如:
HTTP/2 200
content-type: application/x-protobuf
date: Wed, 02 Jun 2021 23:12:37 GMT
content-length: 172
╔╔eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjI1MTQwMTAsInVzZXJuYW1lIjoiNTM1MTAyODA2MCIsInZlcnNpb24iOiIyMTgwNiJ9.Li-bp3bIPdIrsRhuTWEWToS0ds62VCG-a2PCGaKSrigڲօ═"
我没有注意到这一点,因为我认为这些细节是由 CURLOPT_VERBOSE => true
选项引起的。
现在,如何从 CURL 返回的值中提取正文有点复杂,在 this question 你会明白为什么。
我的解决方案如下(我重复一遍,阅读我提到的问题,也许更简单的解决方案适合您):
// I can't trust the Content-Length header (it may or may not be present).
// However, I can reliably calculate the length of the headers and use it instead.
$responseHeadersLength = 0;
$handle = curl_init($url);
$curl_options = [
// ...
CURLOPT_HEADERFUNCTION => function ($curl, $header) use (&$responseHeadersLength) {
$len = strlen($header);
$responseHeadersLength += $len;
return $len;
}
];
curl_setopt_array($handle, $curl_options);
$response = curl_exec($handle);
$body = trim(substr($response, $responseHeadersLength));
我正在执行对服务器的 POST 请求,服务器响应“正确”,但是当尝试调用 mergeFromString()
函数时,我收到以下错误:
Google\Protobuf\Internal\GPBDecodeException: Error occurred during parsing: Unexpected wire type. in Google\Protobuf\Internal\Message.php on line 353
我正在使用 CURL PHP:
$handle = curl_init($url);
$curl_options = [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HEADER => true,
CURLOPT_VERBOSE => true
];
curl_setopt_array($handle, $curl_options);
$curlResponse = curl_exec($handle);
$responseMessage = new MyMessage();
$responseMessage->mergeFromString($curlResponse);
curl_close($handle);
var_dump($curlResponse)
结果如下:
╔╔eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjI1MTQwMTAsInVzZXJuYW1lIjoiNTM1MTAyODA2MCIsInZlcnNpb24iOiIyMTgwNiJ9.Li-bp3bIPdIrsRhuTWEWToS0ds62VCG-a2PCGaKSrigڲօ═"
在纯文本中,它应该看起来像这样:
1: 1
2: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjI1MTQwMTAsInVzZXJuYW1lIjoiNTM1MTAyODA2MCIsInZlcnNpb24iOiIyMTgwNiJ9.Li-bp3bIPdIrsRhuTWEWToS0ds62VCG-a2PCGaKSrig
3: 1619765852
我的响应.proto文件如下:
message MyMessage{
// I'm only interested in property 2
string prop = 2;
}
环境:
"protobuf-php / protobuf": "^ 0.1.3",
"google / protobuf": "^ 3.16"
但是,使用 Protoman (A Postman-like API client for protobuf-based messages) 的测试是成功的。我使用在 PHP.
中使用的相同原型文件进行了测试在这种情况下,错误是因为字符串无效。
并且它是无效的,因为 CURL 返回的值(字符串)包括来自 HTTP 请求的所有数据,例如:
HTTP/2 200
content-type: application/x-protobuf
date: Wed, 02 Jun 2021 23:12:37 GMT
content-length: 172
╔╔eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE2MjI1MTQwMTAsInVzZXJuYW1lIjoiNTM1MTAyODA2MCIsInZlcnNpb24iOiIyMTgwNiJ9.Li-bp3bIPdIrsRhuTWEWToS0ds62VCG-a2PCGaKSrigڲօ═"
我没有注意到这一点,因为我认为这些细节是由 CURLOPT_VERBOSE => true
选项引起的。
现在,如何从 CURL 返回的值中提取正文有点复杂,在 this question 你会明白为什么。
我的解决方案如下(我重复一遍,阅读我提到的问题,也许更简单的解决方案适合您):
// I can't trust the Content-Length header (it may or may not be present).
// However, I can reliably calculate the length of the headers and use it instead.
$responseHeadersLength = 0;
$handle = curl_init($url);
$curl_options = [
// ...
CURLOPT_HEADERFUNCTION => function ($curl, $header) use (&$responseHeadersLength) {
$len = strlen($header);
$responseHeadersLength += $len;
return $len;
}
];
curl_setopt_array($handle, $curl_options);
$response = curl_exec($handle);
$body = trim(substr($response, $responseHeadersLength));