如何用 PHP 强制文件下载

我想要一个文件要下载的用户访问一个 PHP 的网页。我认为它与 file_get_contents有关,但不确定如何执行它。

$url = "http://example.com/go.exe";

使用 header(location)下载文件后,它不会重定向到另一个页面。它只是停止。

554605 次浏览

阅读有关内置 PHP 函数 读文件的文档

$file_url = 'http://www.myremoteserver.com/file.exe';
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"" . basename($file_url) . "\"");
readfile($file_url);

还要确保根据您的文件 application/zip、 application/pdf 等添加适当的内容类型-但只有在您不想触发另存为对话框的情况下。

<?php
$file = "http://example.com/go.exe";


header("Content-Description: File Transfer");
header("Content-Type: application/octet-stream");
header("Content-Disposition: attachment; filename=\"". basename($file) ."\"");


readfile ($file);
exit();
?>

或者,当文件不能在浏览器中打开时,您可以直接使用 Location头:

<?php header("Location: http://example.com/go.exe"); ?>
header("Content-Type: application/octet-stream");
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"file.exe\"");
echo readfile($url);

是正确的

或更好的 前任类型的文件

header("Location: $url");

试试这个:

header('Content-type: audio/mp3');
header('Content-disposition: attachment;
filename=“'.$trackname'”');
readfile('folder name /'.$trackname);
exit();

Http://php.net/manual/en/function.readfile.php

这就够了。“ Monkey.gif”更改为您的文件名。如果您需要从其他服务器下载,“ monkey.gif”改为“ http://www.exsample.com/go.exe

对上述已接受答案的修改,它还在运行时检测 MIME 类型:

$finfo = finfo_open(FILEINFO_MIME_TYPE);
header('Content-Type: '.finfo_file($finfo, $path));


$finfo = finfo_open(FILEINFO_MIME_ENCODING);
header('Content-Transfer-Encoding: '.finfo_file($finfo, $path));


header('Content-disposition: attachment; filename="'.basename($path).'"');
readfile($path); // do the double-download-dance (dirty but worky)

首先显示文件并将其值设置为 url。

Index.php

<a href="download.php?download='.$row['file'].'" title="Download File">

下载

<?php
/*db connectors*/
include('dbconfig.php');


/*function to set your files*/
function output_file($file, $name, $mime_type='')
{
if(!is_readable($file)) die('File not found or inaccessible!');
$size = filesize($file);
$name = rawurldecode($name);
$known_mime_types=array(
"htm" => "text/html",
"exe" => "application/octet-stream",
"zip" => "application/zip",
"doc" => "application/msword",
"jpg" => "image/jpg",
"php" => "text/plain",
"xls" => "application/vnd.ms-excel",
"ppt" => "application/vnd.ms-powerpoint",
"gif" => "image/gif",
"pdf" => "application/pdf",
"txt" => "text/plain",
"html"=> "text/html",
"png" => "image/png",
"jpeg"=> "image/jpg"
);


if($mime_type==''){
$file_extension = strtolower(substr(strrchr($file,"."),1));
if(array_key_exists($file_extension, $known_mime_types)){
$mime_type=$known_mime_types[$file_extension];
} else {
$mime_type="application/force-download";
};
};
@ob_end_clean();
if(ini_get('zlib.output_compression'))
ini_set('zlib.output_compression', 'Off');
header('Content-Type: ' . $mime_type);
header('Content-Disposition: attachment; filename="'.$name.'"');
header("Content-Transfer-Encoding: binary");
header('Accept-Ranges: bytes');


if(isset($_SERVER['HTTP_RANGE']))
{
list($a, $range) = explode("=",$_SERVER['HTTP_RANGE'],2);
list($range) = explode(",",$range,2);
list($range, $range_end) = explode("-", $range);
$range=intval($range);
if(!$range_end) {
$range_end=$size-1;
} else {
$range_end=intval($range_end);
}


$new_length = $range_end-$range+1;
header("HTTP/1.1 206 Partial Content");
header("Content-Length: $new_length");
header("Content-Range: bytes $range-$range_end/$size");
} else {
$new_length=$size;
header("Content-Length: ".$size);
}


$chunksize = 1*(1024*1024);
$bytes_send = 0;
if ($file = fopen($file, 'r'))
{
if(isset($_SERVER['HTTP_RANGE']))
fseek($file, $range);


while(!feof($file) &&
(!connection_aborted()) &&
($bytes_send<$new_length)
)
{
$buffer = fread($file, $chunksize);
echo($buffer);
flush();
$bytes_send += strlen($buffer);
}
fclose($file);
} else
die('Error - can not open file.');
die();
}
set_time_limit(0);


/*set your folder*/
$file_path='uploads/'."your file";


/*output must be folder/yourfile*/


output_file($file_path, ''."your file".'', $row['type']);


/*back to index.php while downloading*/
header('Location:index.php');
?>

如果您必须下载的文件大于允许的内存限制(memory_limit ini 设置) ,这将导致 PHP Fatal error: Allowed memory size of 5242880 bytes exhausted错误,您可以这样做:

// File to download.
$file = '/path/to/file';


// Maximum size of chunks (in bytes).
$maxRead = 1 * 1024 * 1024; // 1MB


// Give a nice name to your download.
$fileName = 'download_file.txt';


// Open a file in read mode.
$fh = fopen($file, 'r');


// These headers will force download on browser,
// and set the custom file name for the download, respectively.
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $fileName . '"');


// Run this until we have read the whole file.
// feof (eof means "end of file") returns `true` when the handler
// has reached the end of file.
while (!feof($fh)) {
// Read and output the next chunk.
echo fread($fh, $maxRead);


// Flush the output buffer to free memory.
ob_flush();
}


// Exit to make sure not to output anything else.
exit;

下面的代码是在 php 中实现下载服务的正确方法,如下面的 教程所述

header('Content-Type: application/zip');
header("Content-Disposition: attachment; filename=\"$file_name\"");
set_time_limit(0);
$file = @fopen($filePath, "rb");
while(!feof($file)) {
print(@fread($file, 1024*8));
ob_flush();
flush();
}

你也可以流式下载,这将大大减少资源消耗。 例如:

$readableStream = fopen('test.zip', 'rb');
$writableStream = fopen('php://output', 'wb');


header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="test.zip"');
stream_copy_to_stream($readableStream, $writableStream);
ob_flush();
flush();

在上面的示例中,我正在下载 test.zip (实际上是本地机器上的 android 工作室 zip)。 //output 是只写流(通常由 echo 或 print 使用)。 之后,您只需要设置所需的头文件,并调用 stream _ copy _ to _ stream (源、目的地)。 Stream _ copy _ to _ stream ()方法作为一个管道,从源流(读流)获取输入,并将其传送到目标流(写流) ,它还避免了 允许内存耗尽的问题,因此实际上可以下载比 PHP memory_limit大的文件。

上面的答案是有效的。但是,我想贡献一个方法来说明如何使用 GET 来执行它

在你的 html/php 页面上

$File = 'some/dir/file.jpg';
<a href="<?php echo '../sumdir/download.php?f='.$File; ?>" target="_blank">Download</a>

download.php包含

$file = $_GET['f'];


header("Expires: 0");
header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
header("Cache-Control: no-store, no-cache, must-revalidate");
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");


$ext = pathinfo($file, PATHINFO_EXTENSION);
$basename = pathinfo($file, PATHINFO_BASENAME);


header("Content-type: application/".$ext);
header('Content-length: '.filesize($file));
header("Content-Disposition: attachment; filename=\"$basename\"");
ob_clean();
flush();
readfile($file);
exit;

这应该适用于任何文件类型。这不是测试使用 POST,但它可以工作。

您可以使用 下载属性强制下载一个文件:

<a href="https://test.com/aaa.exe" download>click here to download</a>