codeigniter 4.5.5 无内置 filecollection 类或批量上传 api,批量处理需手动遍历 getfiles() 返回的数组,结合 uploadedfile 实例逐一验证并移动;directorymap() 仅返回路径字符串,非对象集合。

CodeIgniter 4.5.5 没有内置的「文件集合」(File Collection)抽象类或专用组件,也没有 FileCollection、batchUpload() 或类似 Laravel 的 Filesystem::files() 批量处理 API。所谓“文件集合与批量处理”,实际是开发者基于原生 PHP + CI4 文件工具链组合实现的模式,不是框架原生功能。
CI4.5.5 中没有 FileCollection 类,别被名字带偏
搜索文档或源码你会发现:CodeIgniter\Files\FileCollection 并不存在;Composer require 或 IDE 自动补全也不会出现这个类。CI4 的文件操作核心是:
-
CodeIgniter\Files\File:单个上传文件的封装(含验证、移动、信息读取) -
CodeIgniter\Files\UploadedFile:HTTP 上传上下文中的文件实例(来自$this->request->getFile()) -
CodeIgniter\Files\Files:静态工具类,提供directoryMap()、write_file()等辅助方法(注意不是面向对象集合)
如果你在某教程里看到 new FileCollection(),那要么是自定义封装类,要么是混淆了其他框架概念。
批量上传必须手动遍历 $_FILES,不能只调用一次 getFile()
$this->request->getFile('photos') 只能获取单个 UploadedFile 实例 —— 即使 HTML 表单用了 name="photos[]",CI4 默认也只取第一个。要真正批量处理,必须显式循环原始数组:
// 假设表单字段为 <input type="file" name="photos[]" multiple>
$files = $this->request->getFiles();
if (isset($files['photos']) && is_array($files['photos'])) {
foreach ($files['photos'] as $uploaded) {
if ($uploaded->isValid() && ! $uploaded->hasMoved()) {
$newName = $uploaded->getRandomName();
$uploaded->move(WRITEPATH . 'uploads/', $newName);
}
}
}
常见错误:
- 误用
$this->request->getFile('photos[]')→ 返回 null(CI4 不支持方括号语法解析) - 直接对
$_FILES['photos']调用new UploadedFile()→ 缺少 CI4 的验证上下文,绕过安全检查 - 没检查
$uploaded->isValid()就移动 → 可能写入空/错误文件,甚至触发 PHP 警告
directoryMap() 是唯一接近“文件集合”的内置方法
CodeIgniter\Files\Files::directoryMap() 可递归列出目录下所有文件路径,返回扁平数组,适合做扫描、清理、索引等批量任务:
$paths = \CodeIgniter\Files\Files::directoryMap(WRITEPATH . 'uploads/', 1);
// 返回如 ['photo1.jpg', 'sub/scan.pdf', 'tmp/cache.bin']
foreach ($paths as $path) {
if (pathinfo($path, PATHINFO_EXTENSION) === 'tmp') {
unlink(WRITEPATH . 'uploads/' . $path);
}
}
注意限制:
- 不返回
File对象,只是字符串路径,无法链式调用->getSize()等 - 深度参数(第二个参数)为 1 时只列一级,设为
0才递归全部子目录 - 不区分文件/目录类型,需用
is_file()或is_dir()二次判断
自定义批量处理器要小心生命周期和内存
若你真需要类似 FileCollection 的能力(比如统一验证、批量重命名、事务式移动),建议封装一个轻量服务类,但必须注意:
- 不要在构造函数里一次性
move()所有文件 —— 失败一个会导致前面已移动的无法回滚 - 避免把大文件内容
file_get_contents()全部载入内存,改用流式处理(fopen()+fread()) - CLI 场景下(如命令行批量导入)需手动设置
ini_set('memory_limit', '512M'),Web 请求则受 php.ini 限制更严 - 并发上传时,多个请求共用同一临时目录可能冲突,建议按请求 ID 或时间戳分隔离子目录
最易被忽略的一点:CI4.5.5 的 UploadedFile->move() 不校验目标路径是否可写,也不自动创建父目录 —— mkdir(..., 0755, true) 得自己加,否则静默失败。











