这一回介绍第三种方式。
这里主要用到了nginx的XSendfile功能,这样效率比php的readfile要高。
要使用这个功能首先需要配置nginx:
# nginx 配置
location /check_download {
internal; # 这个设置是必需的
alias /var/www/uploads; # 文件所在真实路径
}
location /check_download {
internal; # 这个设置是必需的
alias /var/www/uploads; # 文件所在真实路径
}
这里使用了 internal 设置,这个设置标明该url无法通过浏览器直接访问。
但是可以通过XSendfile功能访问。
然后,我们需要在php中拦截文件下载处理,并进行权限验证:
首先我们根据下载文件的目录名,在CodeIgniter4添加一个控制器。
例如你的下载目录是 /uploads/.......
这样新建一个控制器 Uploads 就行了。 在控制器的默认方法中进行权限验证,然后调用XSendFile即可。
例如你的下载目录是 /uploads/.......
这样新建一个控制器 Uploads 就行了。 在控制器的默认方法中进行权限验证,然后调用XSendFile即可。
[复制到剪贴板] |
public function getIndex(...$param)
//首先根据 $param 构造文件名
//文件名只有 Uploads 后面的部分。
$subfn = implode('/', $param);
//这里是附件实际路径,通常这个路径应该放在参数配置中
$fn = '/var/www/uploads/' . $subfn;
if (!is_file($fn)) {
return $this->response->setStatusCode(404, '文件不存在');
}
////////////////////////////////////////////////////////
// 模拟校验下载权限
//....
$canDownload = rand(1, 10) > 5;
//...在这里添加你的实际权限判断逻辑
//...
//////////////////////////////////////////
//最后根据权限结果处理
if ($canDownload) {
//这里使用nginx的XSendfile功能
return $this->response->setHeader('X-Accel-Redirect: /check_download/' . $subfn);
} else {
return $this->response->setStatusCode(404, '无权限');
}