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

CakePHP2+PHP7.4中CURL提交超1024字符POST请求超时问题

问题:CURL发送超过1024字符的JSON POST请求超时

我在基于PHP 7.4的CakePHP 2项目中开发,使用CURL发送POST请求时遇到异常:将数据通过json_encode编码为JSON数组后,只要字符数超过1024,CURL就会超时,请求无法发送。

已检查max_input_vars(默认值1000)和post_max_size(设置为2048M,空间充足),但未找到问题根源。曾尝试2009年同类问题的解决方案,无效。

相关代码如下:

/**
 * Perform a request to store the application.
 * TODO: WIP
 */
private function storeApplication()
{
    try {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $this->getEndpoint());
        curl_setopt($ch, CURLOPT_POST, true);

        $customer = $this->application;

        $fields = json_encode([
            'product_type' => 'foo',
            'data_source' => 'foo',
            'data' => [
                'ApiKey' => 'foo',
                'AffId' => 'foo',
                'Application' => [
                    'SubAffId' => '',
                    'ReqRepaymentTerm' => $this->formatField($customer, 'ReqRepaymentTerm'),
                    'AppTitle' => $this->formatField($customer, 'AppTitle'),
                    'AppFirstName' => $this->formatField($customer, 'AppFirstName'),
                    'AppLastName' => $this->formatField($customer, 'AppLastName'),
                    'AppDOBDay' => $this->formatField($customer, 'AppDOBDay'),
                    'AppDOBMonth' => $this->formatField($customer, 'AppDOBMonth'),
                    'AppDOBYear' => $this->formatField($customer, 'AppDOBYear'),
                    'AppMaritalStatus' => $this->formatField($customer, 'AppMaritalStatus'),
                    'AppDependants' => $this->formatField($customer, 'AppDependants'),
                    'AppHomeStatus' => $this->formatField($customer, 'AppHomeStatus'),
                    'AppAddressYears' => $this->formatField($customer, 'AppAddressYears'),
                    'AppHouseNumber' => $this->formatField($customer, 'AppHouseNumber'),
                    'AppPostCode' => $this->formatField($customer, 'AppPostCode'),
                    'AppStreet' => $this->formatField($customer, 'AppStreet'),
                    'AppTown' => $this->formatField($customer, 'AppTown'),
                    'AppCounty' => $this->formatField($customer, 'AppCounty'),
                    'AppEmail' => $this->formatField($customer, 'AppEmail'),
                    'AppMobilePhone' => $this->formatField($customer, 'AppMobilePhone'),
                    'EmpIncomeType' => $this->formatField($customer, 'EmpIncomeType'),
                    'EmpEmployerName' => $this->formatField($customer, 'EmpEmployerName'),
                    'EmpIndustry' => 25,
                    'EmpEmployedMonths' => $this->formatField($customer, 'EmpEmployedMonths'),
                    'EmpPayFrequency' => $this->formatField($customer, 'EmpPayFrequency'),
                    'EmpNetMonthlyPay' => $this->formatField($customer, 'EmpNetMonthlyPay'),
                    'AppLoanPurpose' => $this->formatField($customer, 'AppLoanPurpose'),
                    'AppLoanPrposeOther' => '',
                    'AppHousingSpend' => $this->formatField($customer, 'AppHousingSpend'),
                    'AppCreditSpend' => $this->formatField($customer, 'AppCreditSpend'),
                    'AppUtilitiesSpend' => $this->formatField($customer, 'AppUtilitiesSpend'),
                    'AppFoodSpend' => $this->formatField($customer, 'AppFoodSpend'),
                    'AppTransportSpend' => $this->formatField($customer, 'AppTransportSpend'),
                    'AppOtherSpend' => $this->formatField($customer, 'AppOtherSpend'),
                    'BankName' => $this->formatField($customer, 'BankName'),
                    'BankSortcode' => $this->formatField($customer, 'BankSortcode'),
                    'BankAccount' => $this->formatField($customer, 'BankAccount'),
                ]
            ]
        ]);

        CakeLog::write('debug', "A: ".strlen($fields));

        curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);

        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 5);
        curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type:application/json'));
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);
        curl_setopt($ch, CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_1);
        curl_setopt($ch, CURLOPT_VERBOSE, true); // Enable verbose output

        $string = curl_exec($ch);
        curl_close($ch);

        $res = json_decode($string, true);

        CakeLog::write('debug', json_encode($res));

        // success
        return $res;

    } catch (Exception $e) { }

    // it never saved
    return null;
}

解决方向

  1. 禁用Expect头
    当POST数据超过1024字节时,CURL自动发送Expect: 100-continue头,部分服务器不兼容导致超时。添加空的Expect头禁用该行为:
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Expect:'
));
  1. 手动设置Content-Length
    强制关闭分块传输,手动指定请求内容长度,避免服务器对分块传输的兼容问题:
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
    'Content-Type: application/json',
    'Content-Length: ' . strlen($fields)
));
  1. 延长超时时间
    当前CURLOPT_TIMEOUT设为5秒,大体积数据传输可能需要更长时间:
curl_setopt($ch, CURLOPT_TIMEOUT, 15);
  1. 检查JSON编码有效性
    确认json_encode未产生错误,避免无效JSON导致服务器处理异常:
$fields = json_encode(...);
if (json_last_error() !== JSON_ERROR_NONE) {
    CakeLog::write('error', 'JSON编码错误: ' . json_last_error_msg());
    return null;
}
  1. 排查服务器端限制
    检查目标服务器的max_input_time、防火墙/WAF规则,是否拦截了大体积JSON请求。

内容的提问来源于stack exchange,提问作者Ryan H

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 07:45:55