标题可能会令人困惑,但我将在此处进行解释。
我有一个文件样本。该文件是一个简单的.xml文件,但具有.ciff扩展名和特定的编码(使用的编码为UCS2-LE BOM)。
TEST001.ciff中的内容是:
<?xml version="1.0" encoding="UTF-16"?>
仅此而已。
现在,我正尝试从浏览器下载此文件(不显示内容,而是实际上将其下载到downloads文件夹中),这是到目前为止我在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 " ? >
是否可以下载原始文件的精确副本?我的代码在哪里出错了?
答案 0 :(得分:3)
问题肯定是包含HTML的PHP文件的出现。
如果PHP解析器遇到<?php ?>
标记之外的其他任何内容,则该标记将作为字符串回显给接受它的任何客户端(您的浏览器,作为文件)。
如果这种包含发生在您的实际下载逻辑周围(例如在staff_header.php中),其中包含在输出中看到的HTML,就在实际文件内容之前,您当然会得到同时包含这两个文件的文件, HTML和文件内容,甚至可能使用错误的编码。
可能的解决方案各不相同,并且由于您已经在使用包含文件之类的PHP进行了比较低的工作,因此如果您在包含staff_header.php之前就将下载逻辑移到了正确的位置,可能就足够了。
随着下载代码的退出,如果您进行下载,将永远不会包含标头,但是请注意,通常,将这样的逻辑混淆起来是很不干净的。
即使是只是一个包含if子句的PHP文件来决定是否应执行下载或HTML逻辑,我还是建议将这种逻辑分开并以更高的顺序进行管理。
答案 1 :(得分:0)
这将读取文件并将其下载下载到浏览器。
这是php代码。
$filename = 'Files/' . h($_GET['filename'];
if(file_exists($filename)){
//Get file type and set it as Content Type
$finfo = finfo_open(FILEINFO_MIME_TYPE);
header('Content-Type: ' . finfo_file($finfo, $filename));
finfo_close($finfo);
//Use Content-Disposition: attachment to specify the filename
header('Content-Disposition: attachment; filename='.basename($filename));
//No cache
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
//Define file size
header('Content-Length: ' . filesize($filename));
ob_clean();
flush();
readfile($filename);
exit;
}