PHP CURL调用VirusTotal API返回empty filename错误如何解决?
问题原因
你代码的问题出在调用VirusTotal接口提交文件的逻辑上,共有3个核心错误:
- 你给
$file_to_scan赋值的是公网访问的URL,不是文件在你服务器上的本地存储路径,PHP cURL没法通过这种方式读取远程URL的文件内容用来提交,而且你用的@前缀传文件的语法在PHP5.5及以上版本就已经废弃了,就算写本地路径也不推荐使用。 - 你手动设置了
Content-Type: multipart/form-data请求头,cURL在提交数组类型的POST参数时会自动生成这个请求头,同时会自动拼接表单必须的边界分隔符参数,你手动写这个头会丢失边界信息,导致接口没法正确解析你提交的表单内容,识别不到文件名。 - 没有用PHP官方推荐的
CURLFile类封装文件信息,没法自动携带正确的文件名参数,所以接口返回文件名是空的报错。
修复后的代码
if(isset($_POST["submit"])) { $target_dir = "files/"; // 保留服务器本地的文件路径,不要转成公网URL $target_file = $target_dir . basename($_FILES["file"]["name"]); $filename = basename($_FILES["file"]["name"]); if (move_uploaded_file($_FILES["file"]["tmp_name"], $target_file)) { echo "The file ". htmlspecialchars($filename). " has been uploaded.<hr>"; } else { echo "Sorry, there was an error uploading your file.<hr>"; // 上传失败直接终止,没必要继续调用接口 exit; } $post_url = 'https://www.virustotal.com/api/v3/files'; // 用CURLFile封装本地文件,指定文件MIME类型和文件名 $post['file'] = new CURLFile($target_file, mime_content_type($target_file), $filename); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$post_url); curl_setopt($ch, CURLOPT_POST,1); curl_setopt($ch, CURLOPT_POSTFIELDS, $post); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); $headers = [ 'x-apikey: 12345abcde', 'Accept: application/json' // 删掉手动设置的multipart/form-data头,让curl自动生成 ]; curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); // 如果你的服务器环境HTTPS校验失败,可以临时加下面两行调试,生产环境不建议保留 // curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $api_reply = curl_exec($ch); // 调试阶段可以打印cURL自身的错误信息排查问题 if(curl_errno($ch)) { echo 'cURL错误:' . curl_error($ch); } curl_close($ch); print $api_reply; }
内容的提问来源于stack exchange,提问作者lwd
相关产品推荐
相关产品推荐

