You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用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....."}

问题根源

  1. 请求方法设置冲突:同时设置CURLOPT_POST为true和CURLOPT_CUSTOMREQUEST为'POST'会导致CURL行为异常,可能破坏POST数据的传输格式。
  2. 请求头与数据格式不匹配:请求头声明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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 20:50:33