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

