创建微信支付分订单 curl 请求后处理返回数据
前面提到 微信创建支付分订单报错:“Http头缺少Accept或User-Agent” 解决,在解决了 $header 构建之后,对于处理请求返回数据犯了难。
正常情况下 CURL 返回数据是够用了的,但微信支付分将后续 验签 需要的签名部分信息存放到了响应头部中。这就需要对初始版的 CURL 请求(一般的 CURL 请求只返回响应 body 部分)做一定的修改。
参考 php CURL 请求头和响应头获取 - tianye_guazi ,自己写了一个 Http 请求类:
class Http
{
//
public static function headerHandler($curl, $headerLine) {
$len = strlen($headerLine);
// HTTP响应头是以:分隔key和value的
$split = explode(':', $headerLine, 2);
if (count($split) > 1) {
$key = trim($split[0]);
$value = trim($split[1]);
// 将响应头的key和value存放在全局变量里
$GLOBALS['G_HEADER'][$key] = $value;
}
return $len;
}
public static function headerHandler2($headerStr) {
// HTTP响应头是以:分隔key和value的
$split = array_filter(explode(PHP_EOL, $headerStr), function($v) {
return $v;
});
$headers = [];
for ($i=0; $i < count($split); $i++) {
$pair = explode(':', $split[$i], 2);
// 舍弃掉 HTTP/1.1 200 OK
if (!isset($pair[1])) {
continue;
}
$headers[trim($pair[0])] = trim($pair[1]);
}
return $headers;
}
public static function PostWithHeaders($curlPost, $curlHeader, $url)
{
$curl = curl_init();
// curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, true); // 同时返回响应头
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $curlHeader);
// curl_setopt($curl, CURLINFO_HEADER_OUT, TRUE); // 拿到请求头
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
// curl_setopt($ch, CURLOPT_HEADERFUNCTION, "headerHandler"); // 设置header处理函数
$return_str = curl_exec($curl);
// $request_header = curl_getinfo($curl);
// 获得响应结果里的:头大小
$headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
// 根据头大小去获取头信息内容
$headerStr = substr($return_str, 0, $headerSize);
$response_header = static::headerHandler2($headerStr);
$response_body = json_decode(substr($return_str, $headerSize), true);
// $curl_info = curl_getinfo($curl);
curl_close($curl);
return [
'return_str' => $return_str,
// 'request_header' => $request_header,
'response_header_str' => $headerStr,
'response_header' => $response_header,
'response_body' => $response_body,
// 'curl_info' => $curl_info,
];
}
}
首先是 curl_setopt($curl, CURLOPT_HEADER, true);
将响应头信息与 body 部分一起返回。
之后就需要分离头部和 body。通过 curl_getinfo($curl, CURLINFO_HEADER_SIZE)
先拿到头部信息,再从整个返回字串中截取出 body 部分。headerHandler2
是将头部信息转化为数组,方便读取 Wechatpay-Nonce
、Wechatpay-Signature
、Wechatpay-Timestamp
、Wechatpay-Serial
验签需要的参数。