PHP文件下载前校验问题:Download控制器download_file函数一直返回no
问题诊断与解决方法
我看到你在下载文件前的检查逻辑一直返回“no”,核心问题出在你错误地用HTTP URL调用了file_exists()函数——这个函数只能识别服务器本地的文件系统路径,根本没法处理网络URL!
为什么原来的代码失效?
你用site_url()生成的是类似http://yourdomain.com/uploads/file/xxx.pdf这样的Web地址,但file_exists()需要的是服务器上的物理路径(比如/var/www/html/uploads/file/xxx.pdf)。用URL去调用它,永远会返回false,所以代码一直走到echo "no"的分支。
修正后的Download控制器代码
我们改用CodeIgniter提供的FCPATH常量(指向网站根目录的物理路径)来拼接本地文件路径,同时增加安全校验和优化:
public function download_file($namafile, $nofile) { // 安全处理:过滤文件名,防止目录遍历攻击 $safe_filename = basename($namafile); // 拼接服务器本地的文件路径 $file_path = FCPATH . 'uploads/file/' . $safe_filename; // 检查文件是否存在且可读 if (!file_exists($file_path) || !is_readable($file_path)) { echo "no"; return; // 终止后续执行,避免无效操作 } // 调用force_download下载文件,这里直接传文件内容更高效 force_download($safe_filename, file_get_contents($file_path)); // 如果你想保留原文件路径的文件名,也可以这么写: // force_download($file_path, NULL); echo "yes"; }
下载链接代码优化
可以用更简洁的写法拼接URL,避免重复的echo:
<a href="<?= base_url('download/' . $getFiles['file'] . '/' . $getFiles['nofile']) ?>"> <i class="icon-download"></i> <?= $getFiles['kategori'] ?> </a>
额外注意事项
- 确保服务器上的
uploads/file目录有正确的权限(一般设置为755),让Web服务器进程能读取里面的文件。 - 用
basename()处理文件名是为了防止路径遍历攻击(比如恶意用户传入../config/database.php这样的参数来访问敏感文件),一定要保留这个安全校验。
内容的提问来源于stack exchange,提问作者user9535105
相关产品推荐
相关产品推荐

