CodeIgniter点击下载链接报404,手动输入URL可正常下载
CodeIgniter文件下载问题解决指南
问题描述
- 基于CodeIgniter开发的项目,文件存储在
/upload/books/12/some_book.zip(upload文件夹与application同级) - 页面中点击下载链接
<a href="http://my_ci_project.test/upload/books/12/some_book.zip">download here</a>返回404,但手动在地址栏输入该URL可正常下载 - 使用CI的
force_download()函数时页面空白,执行file_exists(base_url().'upload/books/12/some_book.zip')返回FALSE - 文件权限为644,文件夹权限为755,本地项目路径为
c:\laragon\www\my_ci_project
解决步骤
1. 修复.htaccess路由拦截问题
点击链接报404的核心原因是CI默认路由规则会拦截所有请求,包括静态文件请求,而手动输入URL时服务器直接解析静态文件,绕过了CI路由。修改项目根目录的.htaccess,排除upload文件夹的请求:
RewriteEngine On # 排除upload文件夹,让服务器直接处理其静态文件请求 RewriteCond %{REQUEST_URI} !^/upload/ # 跳过已存在的文件和目录 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # 其余请求交给CI处理 RewriteRule ^(.*)$ index.php/$1 [L]
2. 修正file_exists()的使用方式
file_exists()接收的是本地文件系统路径,而非HTTP URL。用CI提供的FCPATH常量(对应项目根目录)拼接正确路径:
// 正确的本地路径拼接 $local_file_path = FCPATH . 'upload/books/12/some_book.zip'; $file_exists = file_exists($local_file_path); // 此时会正确返回TRUE
3. 修复force_download()空白问题
先加载download helper,使用本地路径而非URL,同时增加文件存在检查:
// 加载下载助手 $this->load->helper('download'); $local_file_path = FCPATH . 'upload/books/12/some_book.zip'; if (file_exists($local_file_path)) { // 读取文件内容,第一个参数是下载时显示的文件名,第二个是文件内容 $file_content = file_get_contents($local_file_path); force_download('some_book.zip', $file_content); } else { echo '目标文件不存在'; }
如果仍空白,检查PHP错误日志,排查是否存在内存不足(大文件可改用分段读取)或Windows权限问题(确保Laragon进程有权限读取该文件)。
4. 备选方案:通过CI控制器处理下载
如果.htaccess修改无效,可创建专门的下载控制器处理请求:
- 创建
application/controllers/Download.php:
class Download extends CI_Controller { public function book($book_id, $filename) { $this->load->helper('download'); // 拼接本地文件路径 $local_path = FCPATH . "upload/books/{$book_id}/{$filename}"; if (file_exists($local_path)) { force_download($filename, file_get_contents($local_path)); } else { show_404(); } } }
- 页面中的下载链接改为:
<a href="http://my_ci_project.test/download/book/12/some_book.zip">download here</a>
内容的提问来源于stack exchange,提问作者zkanoca
相关产品推荐
相关产品推荐

