悠悠楠杉
网站页面
正文:
在企业级应用中,Excel文件的生成与下载是常见需求,但直接暴露文件路径或未做权限校验可能导致数据泄露。本文将结合PHP特性,从安全性和用户体验角度,逐步实现一个健壮的Excel下载方案。
许多开发者会直接使用以下代码实现下载:php
header("Content-type:application/vnd.ms-excel");
header("Content-Disposition:attachment;filename=report.xls");
readfile("/var/www/reports/report.xls");
这种方式的三大风险:
1. 文件路径暴露在URL中
2. 无用户权限验证
3. 服务器资源被恶意消耗
通过会话机制验证用户身份,示例代码:
session_start();
if (!isset($_SESSION['user_id']) || !check_download_permission($_SESSION['user_id'])) {
header("HTTP/1.1 403 Forbidden");
exit("Access denied");
}
将生成的Excel文件保存在非Web目录,并使用随机文件名:php
$safe_dir = '/var/private_reports/';
$file_name = uniqid('report_').'.xlsx';
$file_path = $safe_dir.$file_name;
避免内存溢出,采用分块读取:
header("Content-Length: ".filesize($file_path));
$chunk_size = 1024 * 1024; // 1MB/次
$handle = fopen($file_path, 'rb');
while (!feof($handle)) {
echo fread($handle, $chunk_size);
ob_flush();
flush();
}
fclose($handle);
结合PhpSpreadsheet库的实战代码:
require 'vendor/autoload.php';
use PhpOffice\PhpSpreadsheet\Spreadsheet;
// 1. 权限检查
verify_user_access();
// 2. 生成Excel
$spreadsheet = new Spreadsheet();
$sheet = $spreadsheet->getActiveSheet();
$sheet->setCellValue('A1', '安全审计报告');
// 3. 临时存储
$writer = new Xlsx($spreadsheet);
$temp_file = sys_get_temp_dir().'/'.md5(uniqid()).'.xlsx';
$writer->save($temp_file);
// 4. 安全下载
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="audit_report.xlsx"');
readfile_chunked($temp_file);
// 5. 清理临时文件
register_shutdown_function(function() use ($temp_file) {
if (file_exists($temp_file)) unlink($temp_file);
});
ini
max_execution_time = 300
memory_limit = 512M通过以上方案,既能满足业务需求,又能有效防范常见安全风险。实际部署时还需根据具体业务场景调整验证逻辑和存储策略。