如何用CURL在请求体发送数组?参数缺失问题求助
CURL POST JSON数据未成功传递的问题排查与解决
问题描述
使用PHP CURL发送POST请求传递数组数据时,接收端返回{"mensaje":"parameters are missing","estado":false},但本地var_dump($param)显示参数存在有效数据。当前实现逻辑为:在cero.php的subirResolucion方法中,将包含sistema、id_documento等字段的数组转为JSON后封装进data参数,调用自定义的Page::post方法发起请求。
相关代码
Page类post方法
static public function post($url, $param, $cookie='', $header=array(), $timeout=10) { $curl_handle=curl_init(); curl_setopt($curl_handle, CURLOPT_URL, $url); curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($curl_handle, CURLINFO_HEADER_OUT, true); @curl_setopt($curl_handle, CURLOPT_COOKIELIST, true); curl_setopt($curl_handle, CURLOPT_POST, true); curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $param); if ($cookie!='') { curl_setopt ($curl_handle, CURLOPT_COOKIE, $cookie); } if (count($header)>0) { curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $header); } $body=curl_exec($curl_handle); var_dump($param); $error=curl_error($curl_handle); $head=curl_getinfo($curl_handle, CURLINFO_HEADER_OUT); $cookie=@curl_getinfo($curl_handle, CURLINFO_COOKIELIST); $status_code=curl_getinfo($curl_handle, CURLINFO_RESPONSE_CODE); $str_cookie=self::cookieToString($cookie); curl_close($curl_handle); return array('body'=>$body, 'head'=>$head, 'cookie'=>$str_cookie, 'error'=>$error, 'status' => $status_code); }
cero.php中subirResolucion方法
public function subirResolucion() { $filter = [ 'sistema' => $this->getSistema(), 'id_documento' => $this->getIdDocumento(), 'transparencia' => $this->getTransparencia(), 'archivo' => $this->getArchivo(), ]; $url = $this->getUri(); SysLogger::info("Request URI", print_r($url, true)); $header = [ "Content-Type: application/json", "Authorization: Token ".$this->auth->getToken(), "Cookie: ".$this->auth->getCookie() ]; $param = array('data'=>json_encode($filter)); $response = Page::post($url,$param,'', $header); $body = json_decode($response['body']); return $body; }
调试信息
array(0) { } array(1) { ["data"]=> string(198574) " {"sistema":"erp","id_documento":"19836601","transparencia":"true","archivo":"JVBERi0xLjQKJdPr6eEKMSAwIG9iago8PC9DcmVhdG9yIChNb3ppbGxhLzUuMCBcKFdpbmRvd3MgTlQgMTAuM....."}
问题根源
- 请求方法设置冲突:同时设置
CURLOPT_POST为true和CURLOPT_CUSTOMREQUEST为'POST'会导致CURL行为异常,可能破坏POST数据的传输格式。 - 请求头与数据格式不匹配:请求头声明
Content-Type: application/json,但传递的$param是关联数组,CURL会自动将其编码为application/x-www-form-urlencoded格式,接收端按JSON解析自然无法识别参数。
修复方案
1. 修正Page类post方法
移除CURLOPT_CUSTOMREQUEST设置,避免与CURLOPT_POST冲突:
static public function post($url, $param, $cookie='', $header=array(), $timeout=10) { $curl_handle=curl_init(); curl_setopt($curl_handle, CURLOPT_URL, $url); curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, $timeout); curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, true); curl_setopt($curl_handle, CURLINFO_HEADER_OUT, true); @curl_setopt($curl_handle, CURLOPT_COOKIELIST, true); curl_setopt($curl_handle, CURLOPT_POST, true); // 移除CURLOPT_CUSTOMREQUEST设置,避免请求方法冲突 curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $param); if ($cookie!='') { curl_setopt ($curl_handle, CURLOPT_COOKIE, $cookie); } if (count($header)>0) { curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $header); } $body=curl_exec($curl_handle); var_dump($param); $error=curl_error($curl_handle); $head=curl_getinfo($curl_handle, CURLINFO_HEADER_OUT); $cookie=@curl_getinfo($curl_handle, CURLINFO_COOKIELIST); $status_code=curl_getinfo($curl_handle, CURLINFO_RESPONSE_CODE); $str_cookie=self::cookieToString($cookie); curl_close($curl_handle); return array('body'=>$body, 'head'=>$head, 'cookie'=>$str_cookie, 'error'=>$error, 'status' => $status_code); }
2. 修正subirResolucion方法
直接传递JSON字符串作为POST参数,确保与Content-Type: application/json匹配:
public function subirResolucion() { $filter = [ 'sistema' => $this->getSistema(), 'id_documento' => $this->getIdDocumento(), 'transparencia' => $this->getTransparencia(), 'archivo' => $this->getArchivo(), ]; $url = $this->getUri(); SysLogger::info("Request URI", print_r($url, true)); $header = [ "Content-Type: application/json", "Authorization: Token ".$this->auth->getToken(), "Cookie: ".$this->auth->getCookie() ]; // 直接传递JSON字符串,而非封装为数组 $param = json_encode($filter); $response = Page::post($url, $param, '', $header); $body = json_decode($response['body']); return $body; }
验证说明
修改后,CURL会以application/json格式发送请求体,接收端可正确解析JSON数据,不会再返回参数缺失的错误。
内容的提问来源于stack exchange,提问作者Jake the dog
相关产品推荐
相关产品推荐

