PHP7.4 count()报参数需为数组或实现Countable接口错误 上传失效如何修复
问题修复方案
报错根本原因
该错误是PHP 7.2及以上版本对count()函数的参数校验导致的:当前端表单仅配置单文件上传时,$_FILES['file']['name']是字符串类型,不是数组,传入count()就会触发该警告,后续循环逻辑也无法执行,自然没有上传成功反馈。
同时原有代码还存在两个隐藏问题:
- 多文件场景下获取
$_FILES['file']['size']没有取下标,会导致文件大小校验异常 - 文件名生成逻辑会重复拼接后缀,比如原文件是a.mp4,最终会生成a.mp4.mp4
修复步骤
方案1:支持多文件上传(推荐)
- 修改
index.php中的文件输入框,添加[]后缀和multiple属性,支持选择多个文件:
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>上传文件</title> </head> <body> <form enctype="multipart/form-data" action="upload.php" method="POST"> <input type="file" name="file[]" id="file" multiple> <button type="submit" name="submit" id="submit">上传</button> </form> </body> </html>
- 修改
upload.php逻辑,兼容多文件处理,同时修复原有bug:
<?php if (isset($_POST['submit'])){ // 先判断是否是多文件上传,统一转成数组格式 $fileNames = is_array($_FILES['file']['name']) ? $_FILES['file']['name'] : [$_FILES['file']['name']]; $tmpNames = is_array($_FILES['file']['tmp_name']) ? $_FILES['file']['tmp_name'] : [$_FILES['file']['tmp_name']]; $countfiles = count($fileNames); // 先判断存储目录是否存在,不存在则创建 if (!file_exists('videos')) { mkdir('videos', 0755, true); } // 循环上传所有文件 for($i=0;$i<$countfiles;$i++){ $filename = $fileNames[$i]; $fileExt = explode(".", $filename); $fileActualExt = strtolower(end($fileExt)); // 去掉原文件名的后缀再重新拼接,避免重复后缀 $baseName = pathinfo($filename, PATHINFO_FILENAME); $fileNameNew = $baseName.'.'.$fileActualExt; // 移动文件 if(move_uploaded_file($tmpNames[$i],'videos/'.$fileNameNew)){ echo "文件".$filename."上传成功!<br>"; }else{ echo "文件".$filename."上传失败!<br>"; } } }
方案2:仅保留单文件上传
如果不需要多文件上传,直接修改upload.php为单文件逻辑即可,不需要改前端:
<?php if (isset($_POST['submit'])){ if (!file_exists('videos')) { mkdir('videos', 0755, true); } $filename = $_FILES['file']['name']; $tmpName = $_FILES['file']['tmp_name']; $fileExt = explode(".", $filename); $fileActualExt = strtolower(end($fileExt)); $baseName = pathinfo($filename, PATHINFO_FILENAME); $fileNameNew = $baseName.'.'.$fileActualExt; if(move_uploaded_file($tmpName,'videos/'.$fileNameNew)){ echo "文件上传成功!"; }else{ echo "文件上传失败!"; } }
验证步骤
修改完成后重启MAMP的Apache服务,刷新页面测试上传即可。
内容的提问来源于stack exchange,提问作者Jeremy
相关产品推荐
相关产品推荐

