前言:
近期在接一个第三方支付的时候,遇到一个比较头大的问题,因为第三方会把部分响应结果放在header里传输,需要从头里取数据后解密使用,我在本地是正常的,但是放到服务器上就一直是失败,因为取不到对应的头部信息,找了很久原因也没能找到具体问题所在,初步还是怀疑服务器的配置信息有些差异,不过对于问题的处理已经有了方案。
正文:
首先想要获取头信息需要设置以下参数
curl_setopt($curl, CURLOPT_HEADER, true); //设置header
curl_setopt 文档官网地址:PHP: curl_setopt - Manual
curl_getinfo 文档官网地址PHP: curl_getinfo - Manual
以下面这个请求的返回为例
请求成功后会返回不止一个头部信息,如果只通过普通方式解析头部内容是拿不到正常数据的,对于网上的方案众说纷纭,但是都没有有效的能解决这个问题,对此直接重新对获取头部方法的代码做了优化看下效果
示例代码:
<?php
getHeaders();
getHeadersNew();
/**
* 获取curl请求返回的headers体,使用此方法需要发起请求时先设置 CURLOPT_HEADER = true
* @date 2022/5/19
* @return array
*/
function getHeaders()
{
$headers = array();
$url = '';
$data = "";
$aHeader = [
"Content-Type: application/vnd.5upay-v3.0+json",
];
$curl = curl_init(); //初始化curl
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, true); //设置header
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //要求结果为字符串且输出到屏幕上
curl_setopt($curl, CURLOPT_AUTOREFERER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, $aHeader);
curl_setopt($curl, CURLOPT_POST, 47); //post提交方式
curl_setopt($curl, CURLOPT_TIMEOUT, 10); //以秒计算的超时时间
$result = curl_exec($curl);
$info = curl_getinfo($curl);
echo "------------原始返回头------------".PHP_EOL;
print_r($result);
echo PHP_EOL;
$header_text = substr($result, 0, strpos($result, "\r\n\r\n"));
foreach (explode("\r\n", $header_text) as $i => $line) {
if ($i === 0) {
$headers['http_code'] = $line;
} else {
list ($key, $value) = explode(': ', $line);
$headers[$key] = $value;
}
}
echo "------------普通获取头信息------------".PHP_EOL;;
print_r($headers);
echo PHP_EOL;
return $headers;
}
/**
* 获取头信息升级版用来兼容同时拿到多个http头信息,只返回最终的头信息
* 获取curl请求返回的headers体,使用此方法需要发起请求时先设置 CURLOPT_HEADER = true
* @date 2022/5/21
* @return array
*/
function getHeadersNew()
{
$url = '';
$data = "";
$aHeader = [
"Content-Type: application/vnd.5upay-v3.0+json",
"requestId: 1653042717727dba612ea53feb_wmi",
];
$curl = curl_init(); //初始化curl
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HEADER, true); //设置header
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); //要求结果为字符串且输出到屏幕上
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_HTTPHEADER, $aHeader);
curl_setopt($curl, CURLOPT_POST, 47); //post提交方式
curl_setopt($curl, CURLOPT_TIMEOUT, 10); //以秒计算的超时时间
$result = curl_exec($curl);
$info = curl_getinfo($curl);
// print_r($result);
$headers = array();
//获取头的字节数
$header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
//截取头部全部内容
$header_result = substr($result, 0, $header_size);
//分割为多个数组
$header_text = explode("\r\n\r\n", $header_result);
//过滤空的数组
foreach ($header_text as $k => $y) {
if (empty($y)) {
unset($header_text[$k]);
}
}
$header_text = end($header_text); //去取最后一个也就是最终的header信息
foreach (explode("\r\n", $header_text) as $i => $line) {
if ($i === 0) {
$headers['http_code'] = $line;
} else {
list ($key, $value) = explode(': ', $line);
$headers[$key] = $value;
}
}
echo "------------升级版获取头信息------------".PHP_EOL;;
print_r($headers);
return $headers;
}
如果大家有更好的方案欢迎留言评论