php - PHP readfile() 下载原始文件的精确副本
问题描述
标题可能令人困惑,但我会在这里尝试解释。
我有一个文件样本。该文件是一个简单的 .xml 文件,但具有 .ciff 扩展名和特定编码(使用的编码是 UCS2-LE BOM)。
TEST001.ciff 中的内容是:
<?xml version="1.0" encoding="UTF-16"?>
就这样。
现在我正在尝试从浏览器下载此文件(不显示内容,但实际上将其下载到下载文件夹中),这是我目前在 download.php 文件中使用的代码:
<?php
require_once('../../../private/initialize.php');
require_login();
// Redirect if the logged in user is not with admin level
if($session->level == 'user') {
redirect_to(url_for('/index.php'));
}
include(SHARED_PATH . '/staff_header.php');
if (!empty(h($_GET['filename']))) {
// We have filename request, lets try download it
if (file_exists('Files/' . h($_GET['filename']))) {
// We have the file on the server so we can download it
header("Pragma: public");
header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="'.basename('Files/' . h($_GET['filename'])).'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Content-Length: ' . filesize('Files/' . h($_GET['filename'])));
readfile('Files/' . h($_GET['filename']));
exit;
} else {
// The file was not found on the server
$session->message('The requested file was not found on the server.', false);
redirect_to(url_for('staff/ciff/index.php'));
}
} else {
// The file request was invalid
$session->message('Invalid file request.', false);
redirect_to(url_for('staff/ciff/index.php'));
}
include(SHARED_PATH . '/staff_footer.php');
?>
到目前为止一切顺利,当我单击下载超链接时,文件 TEST001.ciff 被下载到我的下载文件夹中,但是当我打开下载的文件时,我可以看到以下内容:
<!doctype html>
<html lang="en">
<head>
<title>NESI Ticketing - Admin Area</title>
<meta charset="utf-8">
<link rel="stylesheet" media="all" href="/nesiticket/public/stylesheets/staff.css" />
</head>
<body>
<header>
<h1>NESI Ticketing User Area</h1>
</header>
<navigation>
<ul>
<li>Hello, FirstName LastName</li><br />
<li><a href="/nesiticket/public/index.php">Home Page</a></li>
<span> </span>
<li><a href="/nesiticket/public/staff/index.php">Main Menu</a></li>
<span> </span>
<li><a href="/nesiticket/public/staff/logout.php">Logout</a></li>
</ul>
</navigation>
ÿþ< ? x m l v e r s i o n = " 1 . 0 " e n c o d i n g = " U T F - 1 6 " ? >
我可以下载原始文件的精确副本吗?我的代码哪里出错了?
解决方案
问题肯定是包含包含 HTML 的 PHP 文件。如果 PHP 解析器遇到<?php ?>
标签之外的任何其他内容,它将作为字符串回显给任何接受它的客户端(您的浏览器,作为文件)。
如果这种包含发生在您的实际下载逻辑周围,例如在您的情况下使用 staff_header.php,它包含在实际文件内容之前在您的输出中看到的 HTML,那么您当然会得到一个包含 HTML 和文件内容,甚至可能是错误的编码。
可能的解决方案各不相同,并且由于您已经在使用包含文件等的低级别 PHP,如果您在包含您的 Staff_header.php 之前移动下载逻辑可能就足够了。
当下载代码退出时,如果您的下载发生,标头将永远不会包含在内,但请注意,通常情况下,像这样混淆逻辑是相当不干净的。
我建议保持这种逻辑的分离和更高的顺序管理,即使它只是另一个包含 if 子句的 PHP 文件,它决定是否应该执行下载或 HTML 逻辑。
推荐阅读
- r - 通过循环遍历数据框中的变量名称,使用 ggpubr 和 rstatix 创建一组图
- spring-boot - springboot中的tomcat webserver/servlet container/dispatcher servlet交互
- firebase - 在不知道文档 ID 的情况下添加子集合
- python - Numpy追加不向Numpy数组添加行
- html - 如何创建带有编号输入的文本字段?
- javascript - 使用 react-native-track-player 正确切换播放状态以进行实时音频流 React Native 应用程序(shoutcast)
- python - 如何将数组从 MongoDB 转换为 HTML 中的字符串?
- java - 套接字读取 IOException 没有被捕获?
- html - 在重叠图像上应用 CSS 动画
- linux - /bin/sh: 无法访问 tty;作业控制已关闭