PHP如何实现下载文件时动态修改扩展名为gpx且不写入服务端
实现方法
你不需要修改服务器上存储的原xml文件,HTTP下载的文件名完全由Content-Disposition响应头的filename参数决定,仅修改响应头配置即可实现下载时自动替换为gpx后缀,修改方案如下:
核心修改点
- 替换
Content-Disposition头中的文件名:提取原xml文件的主文件名,拼接.gpx作为下载文件名 - 可选优化:将MIME类型修改为gpx标准格式
application/gpx+xml,提升GPS设备的识别兼容性 - 新增路径安全校验:修复原代码存在的路径遍历漏洞,避免用户下载服务器敏感文件
修改后完整代码
function myFunction($navn) { // 安全校验:限制仅允许读取指定目录下的xml文件,防止路径遍历攻击 $allowedDir = __DIR__ . '/你的路线xml文件存储目录/'; // 替换为你实际存放路线文件的目录绝对路径 $realPath = realpath($allowedDir . basename($navn)); if (!$realPath || str_starts_with($realPath, $allowedDir) !== true || pathinfo($realPath, PATHINFO_EXTENSION) !== 'xml') { http_response_code(403); exit('非法请求'); } $path = $realPath; // 改为gpx标准MIME类型,兼容性更好 $mm_type = "application/gpx+xml"; // 提取原文件主名,替换后缀为gpx $fileName = pathinfo($path, PATHINFO_FILENAME) . '.gpx'; header("Pragma: public"); header("Expires: 0"); header("Cache-Control: must-revalidate, post-check=0, pre-check=0"); header("Cache-Control: public"); header("Content-Description: File Transfer"); header("Content-Type: " . $mm_type); header("Content-Length: " . filesize($path)); header('Content-Disposition: attachment; filename="'.$fileName.'"'); header("Content-Transfer-Encoding: binary\n"); readfile($path); exit(); } if (isset($_GET['name'])) { $navn = $_GET['name']; myFunction($navn); }
低版本PHP兼容说明
如果你的PHP版本低于8.0,没有内置str_starts_with函数,可以替换为下面的判断逻辑:
if (strpos($realPath, $allowedDir) !== 0) { http_response_code(403); exit('非法请求'); }
内容的提问来源于stack exchange,提问作者pknudsen
相关产品推荐
相关产品推荐

