[我正在使用php脚本在需要的JavaScript计时器之后提供从我的网站提供的下载,此php脚本已包括在内,这导致下载。但是无论我如何尝试,下载的文件都已损坏。谁能帮我指出我要去哪里了。
这是我的代码
<?php
include "db.php";
$id = htmlspecialchars($_GET['id']);
$error = false;
$conn = mysql_connect(DB_HOST,DB_USER,DB_PASSWORD);
if(!($conn)) echo "Failed To Connect To The Database!";
else{
if(mysql_select_db(DB_NAME,$conn)){
$qry = "SELECT Link FROM downloads WHERE ID=$id";
try{
$result = mysql_query($qry);
if(mysql_num_rows($result)==1){
while($rows = mysql_fetch_array($result)){
$f=$rows['Link'];
}
//pathinfo returns an array of information
$path = pathinfo($f);
//basename say the filename+extension
$n = $path['basename'];
//NOW comes the action, this statement would say that WHATEVER output given by the script is given in form of an octet-stream, or else to make it easy an application or downloadable
header('Content-type: application/octet-stream');
header('Content-Length: ' . filesize($f));
//This would be the one to rename the file
header('Content-Disposition: attachment; filename='.$n.'');
//Finally it reads the file and prepare the output
readfile($f);
exit();
}else $error = true;
}catch(Exception $e){
$error = true;
}
if($error)
{
header("Status: 404 Not Found");
}
}
}
?>
首先,正如某些人在评论中指出的那样,删除第一行中打开PHP标记(<?php
)之前的所有空格,这应该可以解决问题(除非此文件包含在其他文件中或由其他文件要求) )。
当您在屏幕上打印任何内容时,即使只有一个空格,您的服务器也会将标题和要打印的内容一起发送(在这种情况下为空白)。为了防止这种情况发生,您可以:
a)在完成标题之前不打印任何内容;
b)首先将ob_start()作为脚本中的第一件事,编写内容,编辑标题,然后在希望将内容发送到用户的浏览器时进行ob_flush()和ob_clean()的处理。
在b)中,即使您成功编写了头文件而没有收到错误,空格也会破坏您的二进制文件。您只应编写二进制内容,而不能在二进制内容中写一些空格。
ob _前缀代表输出缓冲区。调用ob_start()
时,您告诉应用程序输出的所有内容(echo
,printf
等)都应保留在内存中,直到您明确告诉它“去”(ob_flush()
)给客户端为止。这样,您就可以将输出与标头一起保存,当您完成对标头的编写后,它们将与内容一起发送。
[这在打开更多输出缓冲区的情况下对我有帮助。
//NOW comes the action, this statement would say that WHATEVER output given by the script is given in form of an octet-stream, or else to make it easy an application or downloadable
header('Content-type: application/octet-stream');
header('Content-Length: ' . filesize($f));
//This would be the one to rename the file
header('Content-Disposition: attachment; filename='.$n.'');
//clean all levels of output buffering
while (ob_get_level()) {
ob_end_clean();
}
readfile($f);
exit();
ob_start();//add this to the beginning of your code
if (file_exists($filepath) && is_readable($filepath) ) {
header('Content-Description: File Transfer');
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=$files");
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Pragma: public');
header("content-length=".filesize($filepath));
header("Content-Transfer-Encoding: binary");
/*add while (ob_get_level()) {
ob_end_clean();
} before readfile()*/
while (ob_get_level()) {
ob_end_clean();
}
flush();
readfile($filepath);