背景
工作中经常需要对接第三方系统,经常遇到 curl 参数报错异常的问题。
curl post 传递参数
$url = 'xxx.kangxuanpeng.com/xx/server';
$data = ['param' => 'test'];
$ch = curl_init($url);
$head_array = array('application/x-www-form-urlencoded');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($req_array));
curl_setopt($ch, CURLOPT_HTTPHEADER, $head_array);
$response = curl_exec($ch);
参数经过 http_build_query()
转换成 key 对应 value 值的绑定发送到第三方,问题就在于 http_build_query()
进行的符号加密。
问题定位
如果参数无特殊符号, http_build_query()
正常加密:
$param = ['param' => 'test', 'blog' => 'HongXunPan'];
echo http_build_query($param);
//param=test&blog=HongXunPan
但是如果参数中有特殊参数的话,就不一样了:
$param = ['param' => 'test','blog' => 'HongXunPan', 'url' => 'https://blog.kangxuanpeng.com/','time' => '2020-06-18 22:00:00'];
echo http_build_query($param);
//param=test&blog=HongXunPan&url=https%3A%2F%2Fblog.kangxuanpeng.com%2F&time=2020-06-18+22%3A00%3A00
然而恰好是对 /
符号的转换,第三方系统无法识别。
解决方法
问题找到了就很好定位了,只需要自己实现一个方法手动进行拼接即可。
function transferArrayToSignString($req_array)
{
$str = '';
foreach ($req_array as $key => $value) {
if ($str != '') {
$str .= '&';
}
$str .= $key.'='.$value;
}
return $str;
}
大功告成:
$param = ['param' => 'test','blog' => 'HongXunPan', 'url' => 'https://blog.kangxuanpeng.com/','time' => '2020-06-18 22:00:00'];
echo http_build_query($param);
//param=test&blog=HongXunPan&url=https%3A%2F%2Fblog.kangxuanpeng.com%2F&time=2020-06-18+22%3A00%3A00
echo transferArrayToSignString($param);
//param=test&blog=HongXunPan&url=https://blog.kangxuanpeng.com/&time=2020-06-18 22:00:00