Codeigniter上传CSV时mime_type为text/x-Algol68导致上传失败如何处理
解决方案
框架层面方案(推荐,不依赖服务器配置)
- 确认mime配置修改路径正确
需保证修改的是application/config/mime.php而非system/config/mime.php,Codeigniter会优先加载应用目录下的配置文件,且修改系统目录下的配置会在框架版本升级时被覆盖。如果你之前修改的是系统目录下的文件,把csv对应的mime配置同步到应用目录的mime.php中即可。 - 扩展CI上传类(最优方案,无侵入核心代码)
不要直接修改system/libraries/Upload.php,而是在application/libraries目录下新建MY_Upload.php文件,重写mime检测逻辑,对后缀为.csv的文件放宽校验:<?php class MY_Upload extends CI_Upload { public function is_allowed_filetype($ignore_mime = FALSE) { // 后缀为csv的文件直接校验后缀,绕过mime误判问题 $ext = strtolower(pathinfo($this->file_name, PATHINFO_EXTENSION)); if ($ext === 'csv') { return in_array($ext, explode('|', $this->allowed_types)); } // 其他类型走原有校验逻辑,不影响上传安全性 return parent::is_allowed_filetype($ignore_mime); } } - 自定义上传验证逻辑
也可以在上传控制器中自行实现校验规则,示例代码如下:// 上传配置 $config['upload_path'] = './uploads/'; $config['allowed_types'] = '*'; // 临时关闭自带mime校验 $config['max_size'] = '100000'; $config['file_name'] = 'new_'.date('d-M-Y_H:i:s').'_' . substr(md5(time()), 0, 16); $this->load->library('upload', $config); if (!$this->upload->do_upload('file')) { // 处理上传基础错误 } else { $upload_data = $this->upload->data(); $ext = strtolower($upload_data['file_ext']); // 校验后缀合法性 if (!in_array($ext, ['.csv', '.xls', '.xlsx'])) { unlink($upload_data['full_path']); // 删除非法文件 $this->session->set_flashdata('error', '仅允许上传csv、xls、xlsx格式文件'); redirect('你的上传页面地址'); } // 可额外校验CSV文件内容合法性,提高安全性 if ($ext === '.csv') { $handle = fopen($upload_data['full_path'], 'r'); if ($handle === FALSE) { unlink($upload_data['full_path']); $this->session->set_flashdata('error', '上传的CSV文件格式无效'); redirect('你的上传页面地址'); } fclose($handle); } // 后续业务逻辑 }
服务端层面方案
- 修改服务器mime配置
Nginx环境下,编辑nginx/conf/mime.types文件,调整csv的mime优先级,将text/csv csv;放在文本类型配置的靠前位置,重载nginx配置即可生效。
Apache环境下,可在站点根目录的.htaccess文件中添加配置:AddType text/csv .csv - 更新系统magic数据库
出现该误判的核心原因是系统自带的file命令依赖的magic数据库版本过旧,旧版本会把开头含REF字符串的文本文件识别为text/x-Algol68,将系统的file工具包更新到最新版本即可修复该底层识别问题。
内容的提问来源于stack exchange,提问作者Esar-ul-haq Qasmi
相关产品推荐
相关产品推荐

