根本不是codeigniter 3框架问题,而是必须同步调大php(upload_max_filesize、post_max_size、memory_limit、超时)、nginx(client_max_body_size、client_body_timeout、proxy_read_timeout)及upload_tmp_dir权限,缺一不可。

CodeIgniter 3 上传大文件超时中断,根本不是框架本身的问题,而是 PHP 和 Nginx(或 Apache)在中间层层拦截——只调大 CodeIgniter 的 $config['max_size'] 没用,必须同步打通三道关卡。
PHP upload_max_filesize 和 post_max_size 必须成对调大
CodeIgniter 3 的上传类依赖 PHP 原生的 $_FILES,而 PHP 在解析请求体前就按 upload_max_filesize 和 post_max_size 做硬拦截。只要任一值不够,$_FILES 就为空,CI3 甚至收不到错误,直接跳过验证逻辑。
-
upload_max_filesize控制单个文件上限,比如设为512M -
post_max_size必须 ≥upload_max_filesize,还要额外加几十 MB(multipart boundary 和字段开销),建议设为520M -
memory_limit至少设为1G,否则 PHP 解析大 POST 时内存溢出,进程崩溃 -
max_execution_time和max_input_time都要设为 ≥600(10 分钟),否则上传中途被 PHP 强制终止 - 改完后必须
sudo systemctl restart php8.2-fpm(或对应版本),reload不生效
Nginx client_max_body_size 和 client_body_timeout 得配得准
如果用了 Nginx,它会在请求抵达 PHP 前就拦下超大的 body。常见症状是 413 Request Entity Too Large,或者上传到一半突然断连、返回空白页——这时候 CI3 根本没机会执行,日志里也找不到痕迹。
-
client_max_body_size必须 ≥ PHP 的post_max_size,例如写成512M -
client_body_timeout设为 600 秒,防慢速上传被断(比如用户用手机上传,网络抖动) - 若用
proxy_pass转发给 PHP-FPM,还得加proxy_read_timeout 600(等 PHP 返回响应)和proxy_send_timeout 600(等 PHP 接收完请求体) - 配置要放在
location ~ \.php$或具体 upload 路由块里,别只塞在server块顶层,否则可能不生效
CI3 上传类的 timeout 参数无效,别白费劲
CodeIgniter 3 的上传类没有内置超时控制机制。$config['max_size'] 只校验文件大小,$config['timeout'] 这个键根本不存在——文档里没写,源码里也没实现。试图在控制器里加 set_time_limit(0) 也救不了,因为 PHP 层级的超时(max_execution_time)和 Nginx 层级的连接超时(client_body_timeout)早就把请求掐死了。
- 不要在 CI3 上传逻辑里写
ini_set('max_execution_time', '0'),它无法绕过 Nginx 的client_body_timeout - 不要指望
$this->upload->initialize($config)支持 timeout 参数,CI3 源码system/libraries/Upload.php中无相关处理 - 真正起作用的是 PHP ini 设置 + Nginx 配置 + 后端接收速率(比如 PHP 脚本是否及时调用
move_uploaded_file())
上传目录权限和临时目录必须可控
CI3 把文件先存到 PHP 的 upload_tmp_dir,再移动到你指定的 upload_path。如果临时目录不可写、空间不足、或被系统定时清理(比如 /tmp),就会静默失败:文件没传过去,$_FILES['userfile']['error'] 还是 0,CI3 以为成功了,但 move_uploaded_file() 返回 false。
- 在
php.ini里显式设置upload_tmp_dir = /var/www/myapp/uploads/tmp,确保该路径存在且www-data可写 -
$config['upload_path']对应的目录也要chmod 755,并确认磁盘有足够空间 - 上传前加一行日志:
log_message('debug', 'tmp dir: ' . ini_get('upload_tmp_dir'));,确认实际走的是哪个路径 - 避免用相对路径如
./uploads/,CI3 在 CLI 环境下可能解析错,统一用绝对路径
真正卡住上传的,从来不是 CI3 的代码行数,而是 PHP ini 里那几行、Nginx 配置里那几个 timeout 值、还有那个没人检查的 upload_tmp_dir 权限。调参时漏掉任意一环,上传都会在某个环节无声消失。











