使用CURL通过AJAX上传文件至post.php时,$_FILES为空如何解决?
解决CURL上传文件时$_FILES为空的问题
嘿,我来帮你排查这个问题!你现在遇到的情况是:通过AJAX提交数据后用CURL发送到post.php,结果$_FILES是空数组,本该是文件的数据反而出现在$_POST['temp_upload_file']里,值是@/tmp/php6OHgQc;filename=Penguins.jpg;type=image/jpeg。
问题出在哪?
主要有两个关键点:
- 手动设置
Content-type请求头搞砸了:当你用CURL上传文件时,只要给CURLOPT_POSTFIELDS传的是包含文件路径的数组,CURL会自动生成正确的multipart/form-data请求头,还会带上必要的边界符(boundary)。你手动设置这个头的话,CURL就没法正确识别文件字段,直接把整个字符串当成普通POST参数处理了,所以文件数据就跑到$_POST里了。 @符号的上传方式已经过时:从PHP 5.5开始,用@加文件路径的方式已经被废弃,官方推荐用CURLFile类来处理文件上传,不仅更安全,还能避免很多兼容性问题。
修正后的代码(推荐版,PHP 5.5+)
$url = "post.php"; $ch = curl_init($url); // 用CURLFile类封装文件信息 $uploadFile = new CURLFile( $_FILES['uploadfile']['tmp_name'], $_FILES['uploadfile']['type'], $_FILES['uploadfile']['name'] ); $data = ['temp_upload_file' => $uploadFile]; curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 重点:删掉手动设置Content-type的代码,让CURL自动处理 // curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: multipart/form-data')); echo curl_exec($ch); $info = curl_getinfo($ch); curl_close($ch);
兼容老版本PHP的方案(不推荐,仅作参考)
如果你的PHP版本低于5.5(真的建议升级了),可以保留@的方式,但必须删掉手动设置的Content-type请求头:
$url = "post.php"; $ch = curl_init($url); curl_setopt($ch, CURLOPT_POST, true); $data = [ 'temp_upload_file' => '@'.$_FILES['uploadfile']['tmp_name'].';filename='.$_FILES['uploadfile']['name'].';type='. $_FILES['uploadfile']['type'] ]; curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // 关键:不要手动设置Content-type // curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: multipart/form-data')); echo curl_exec($ch); $info = curl_getinfo($ch); curl_close($ch);
这样修改之后,你再去post.php里打印$_FILES,就能正常获取到上传的文件信息啦!
内容的提问来源于stack exchange,提问作者abhay patel
相关产品推荐
相关产品推荐

