PHP 8.2.15中CURLOPT_POSTFIELDS为何不接受数组?
CURLOPT_POSTFIELDS传数组时php://input为空的原因
问题描述
使用PHP 8.2.15版本时,遇到CURLOPT_POSTFIELDS传数组后,目标文件通过file_get_contents('php://input')获取不到请求体的问题。测试代码如下:
temp.php
exit(file_get_contents('php://input'));
test.php
$fields = ['foo' => 'bar']; $config = [ \CURLOPT_RETURNTRANSFER => true, \CURLOPT_ENCODING => '', \CURLOPT_MAXREDIRS => 10, \CURLOPT_TIMEOUT => 10, \CURLOPT_FOLLOWLOCATION => true, \CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, ]; $with_array_handle = \curl_init('http://localhost/temp.php'); \curl_setopt_array($with_array_handle, $config + [\CURLOPT_POSTFIELDS => $fields]); $with_string_handle = \curl_init('http://localhost/temp.php'); \curl_setopt_array($with_string_handle, $config + [\CURLOPT_POSTFIELDS => http_build_query($fields)]); echo '<pre>' . curl_exec($with_array_handle) . '</pre>'; echo '<pre>' . curl_exec($with_string_handle) . '</pre>';
测试结果:数组方式请求的php://input为空,仅字符串方式能返回foo=bar,但PHP文档明确说明CURLOPT_POSTFIELDS可接受数组,此行为看似矛盾。
原因分析
- 当
CURLOPT_POSTFIELDS传入数组时,curl会自动将请求的Content-Type设置为multipart/form-data,这是用于上传文件或复杂表单数据的编码格式。 - PHP处理
multipart/form-data请求时,会自动解析请求体内容到$_POST、$_FILES超全局变量中,不会保留原始内容在php://input里,因此file_get_contents('php://input')返回空。 - 当传入字符串(如
http_build_query生成的结果)时,curl默认使用application/x-www-form-urlencoded格式,PHP不会清空php://input,因此能获取到原始请求体。
验证方法
修改temp.php为以下代码,可直观看到两种请求方式的差异:
// temp.php echo "php://input内容:" . file_get_contents('php://input') . "\n"; echo "\n"; echo "\$_POST内容:"; var_dump($_POST);
运行test.php后,数组方式请求会输出$_POST中的['foo' => 'bar'],但php://input为空;字符串方式则两种方式都能获取到对应内容。
内容的提问来源于stack exchange,提问作者tvanc
相关产品推荐
相关产品推荐

