上传失败主因是配置与环境问题:先确认upload_path目录存在且可写、路径正确,再检查MIME类型是否匹配,二者占失败80%以上。

上传失败绝大多数不是代码写错了,而是配置没对或环境没准备好。先确认 upload_path 目录存在、可写、路径写对了,再查 MIME 类型是否被拒绝——这两点占所有失败的 80% 以上。
upload_path 配置错误导致“Unable to write file to disk”
这个错误表面是磁盘写入失败,实际常因路径不存在、权限不足或用了相对路径却没从 webroot 开始算起。
-
upload_path必须是服务器上真实存在的目录,且 PHP 进程有写权限(常见设为chmod 755或777,生产环境慎用777) - 写成
'./uploads/'时,实际路径是相对于index.php所在位置,不是控制器或视图所在目录 - 推荐用绝对路径:
FCPATH . 'uploads/'(FCPATH是 CodeIgniter 定义的常量,指向 front controller 目录) - 上传前加一行检查:
if (!is_writable($config['upload_path'])) die('Upload dir not writable');
allowed_types 被 MIME 类型校验拦截
即使表单传的是 .jpg,CodeIgniter 也会读取文件头判断真实 MIME 类型,并去 application/config/mimes.php 查匹配项。不匹配就报“The filetype you are attempting to upload is not allowed.”
- 不要只靠扩展名判断——
allowed_types = 'jpg|png'不等于“允许 JPG 文件”,它只是告诉 CI 去查mimes.php中jpg对应的 MIME 列表(如image/jpeg) - 如果上传失败但扩展名没错,打开
application/config/mimes.php,确认对应扩展名的 MIME 数组里包含你实际收到的类型(例如某些安卓相册导出的 PNG 可能报image/x-png,而默认配置里只有image/png) - 临时调试可加
$this->upload->set_allowed_types('*');(CI 3.1.11+),但上线前必须关掉 - CI 2.x 中该逻辑在
is_allowed_filetype()方法里,CI 3.x 已重构,行为更严格
do_upload() 参数为空或字段名不一致
表单中 <input type="file" name="avatar">,但代码里写 $this->upload->do_upload('userfile'),就会直接返回 false 且无明确提示。
- 务必确保
do_upload()的参数和 HTML 表单中name属性值完全一致(区分大小写) - 如果没传参数(
do_upload()空调用),CI 默认找userfile字段,但现代表单基本不用这个名字 - 多文件上传不能复用同一个
upload实例——每次循环前要重新$this->upload->initialize($config) - CI 3.x 中,
do_upload()返回布尔值,错误信息只能通过$this->upload->display_errors()拿,不会抛异常
encrypt_name 和 file_name 冲突导致覆盖或失败
设了 encrypt_name = TRUE 还手动指定 file_name,会导致文件名生成逻辑冲突,有时静默失败或生成空文件名。
-
encrypt_name = TRUE会忽略file_name设置,自动生成哈希名(如4a7d1ed414474e4033ac29ccb8653d9b.jpg) - 想自定义命名,就关掉
encrypt_name,并确保file_name不带扩展名(CI 会自动拼接) - 设
overwrite = FALSE时,重名文件会被加上数字后缀(photo_1.jpg),但前提是file_name是基础名,不是完整路径 - 注意:CI 不会自动创建子目录,
upload_path = './uploads/2026/04/'要提前建好,否则报错
最常被跳过的其实是 mimes.php 的适配和上传目录的绝对路径验证——很多开发者改完配置就跑,却没进服务器确认目录是否存在、PHP 是否真能写进去。上传类本身很稳定,问题几乎全出在环境与配置的衔接处。


















