在yii2中强制下载文件应使用 response 组件的 sendfile() 方法,通过设置 content-disposition 为 attachment 触发浏览器下载行为。调用时传入文件路径和可选的自定义文件名即可,该方法会自动处理 mime 类型并结束请求。

如何配置 Response 以触发附件下载
实现强制下载的核心在于修改响应头中的 Content-Disposition 字段。Yii2 的 yii\web\Response 对象提供了 sendFile() 方法,它内部封装了设置该头部以及读取文件内容的逻辑。开发者只需实例化或获取当前应用的 Response 对象,调用此方法并指定本地文件路径,框架便会将文件流发送给客户端。

$response = Yii::$app->response;
$response->sendFile('/path/to/file.pdf', 'custom_name.pdf');上述代码展示了最基础的用法。第一个参数是服务器上的绝对路径,第二个参数是下载时显示给用户的文件名。如果省略第二个参数,默认使用原文件名。执行后,浏览器会弹出“另存为”对话框而不是直接打开文件。
如何处理大文件或需要自定义 MIME 类型的场景
当文件较大或需要精确控制内容类型时,直接使用 sendFile() 可能不够灵活。此时可以手动构建 Response 对象,设置 headers 并使用 sendStreamAsFile() 或直接输出流。这种方法允许在发送前进行权限校验或日志记录,同时支持分块传输以减少内存占用。

$fileInfo = new SplFileInfo('/path/to/large_file.zip');
$mimeType = $fileInfo->getMimeType();
$response = Yii::$app->response;
$response->headers->set('Content-Type', $mimeType);
$response->headers->set('Content-Disposition', 'attachment; filename="large_file.zip"');
$fileHandle = fopen('/path/to/large_file.zip', 'rb');
$response->sendStreamAsFile($fileHandle, 'large_file.zip');
exit;这段代码演示了如何手动设置 MIME 类型并处理文件句柄。对于超大文件,建议结合 sendStreamAsFile() 使用,因为它能更好地处理流式传输。注意最后必须调用 exit 或确保没有后续输出,以防止响应体被破坏。
sendFile 方法在遇到不存在的路径时会返回什么
当 sendFile() 接收到一个不存在的文件路径时,它会抛出 yii\web\HttpException 异常,具体为 404 状态码。这是因为该方法内部会检查文件是否存在且可读,若检查失败则不会继续执行后续的头部设置和流发送操作。开发者应在调用前使用 file_exists() 进行预判,或在控制器中使用 try-catch 块捕获该异常以提供友好的错误提示。


















