PHP - 如何强制下载文件?

27

我想在我的网站上每个视频下面添加一个“下载此文件”功能。由于有时会在浏览器中播放文件,因此需要强制用户下载文件,而不是仅仅提供链接。问题是,视频文件存储在另一台服务器上。

有没有办法在PHP中强制下载?


可能是使用PHP强制下载文件的重复问题。 - bummi
7个回答

56

你可以尝试像这样做:

<?php

// Locate.
$file_name = 'file.avi';
$file_url = 'http://www.myremoteserver.com/' . $file_name;

// Configure.
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary"); 
header("Content-disposition: attachment; filename=\"".$file_name."\"");

// Actual download.
readfile($file_url);

// Finally, just to be sure that remaining script does not output anything.
exit;

我刚测试了一下,对我有效。

请注意,要使readfile能够读取远程URL,您需要启用fopen_wrappers


只需记得执行以下代码:str_replace('"', '\"', $file_name)然后再将其放入头文件中。 - Chris KL
7
问题在于所有视频都将通过他的服务器运行。如果由于带宽原因视频存储在另一台服务器上,这个解决方案就不可接受。 - Zoredache
1
我认为使用readfile会消耗两个网站的带宽。有人想这样做的主要原因是为了节省一些带宽。 - pouya
我假设是一样的。@pouya。服务器必须下载文件,然后用户从服务器下载文件。 - Ben
1
@Ben 如果你可以访问拥有该文件的服务器,你可以直接从服务器上使用readfile读取文件,而不是远程读取,这样就可以避免双重带宽问题。 - Paolo Bergantino
显示剩余5条评论

6

测试过的 download.php 文件如下:

function _Download($f_location, $f_name){
  $file = uniqid() . '.pdf';

  file_put_contents($file,file_get_contents($f_location));

  header('Content-Description: File Transfer');
  header('Content-Type: application/octet-stream');
  header('Content-Length: ' . filesize($file));
  header('Content-Disposition: attachment; filename=' . basename($f_name));

  readfile($file);
}

_Download($_GET['file'], "file.pdf");

下载链接为

<a href="download.php?file=http://url/file.pdf"> Descargar </a>

4

试试这个:

<?php
$FileName = '/var/ww/file.txt';
header('Content-disposition: attachment; filename="'.$FileName.'"');
readfile($FileName);

关键在于header()。您需要将头文件与下载一起发送,这将强制用户浏览器中出现“保存文件”对话框。


1
<?php

    $file_name = 'video.flv';
    $file_url = 'http://www.myserver.com/secretfilename.flv';
    header('Content-Type: application/octet-stream');
    header("Content-Transfer-Encoding: Binary"); 
    header("Content-disposition: attachment; filename=\"".$file_name."\""); 
    echo file_get_contents($file_url);
    die;

?>

请提供您解决方案的更详细描述。 - clemens

0

我不知道这是否是最佳方式,但我喜欢它,简短且简单。

如果你想要在访问 URL 时下载文件,可以像下面这样做:

<a href="resume.pdf" download></a>
<script>document.querySelector('a').click();</script>

0

index.php

<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>download</title>
</head>

<body>
        <a href="download.php?file=ID_do_arquivo"> download </a>
</body>
</html>

.htaccess

Options -Indexes
Options +FollowSymlinks
deny from all

download.php

$file = "pdf/teste.pdf";
 if (file_exists($file)) {
    header('Content-Description: File Transfer');
    header('Content-Type: application/octet-stream');
    header('Content-Disposition: attachment; filename='.basename($file));
    header('Content-Transfer-Encoding: binary');
    header('Expires: 0');
    header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
    header('Pragma: public');
    header('Content-Length: ' . filesize($file));
    ob_clean();
    flush();
    readfile($file);
    exit();
}

1
虽然你的代码看起来很棒,很可能也回答了问题,但请添加一个解释说明它是如何工作的,以便人们能够理解为什么它能够工作。 - Unbranded Manchester

-1
<?php
$FileName = '/var/ww/file.txt';
header('Content-disposition: attachment; filename="'.$FileName.'"');
readfile($FileName);

使用这段代码,你能否将文件名保存为你想要的名称呢?例如,你有一个URL:http://remoteserver.com/file.mp3,你能否使用这个脚本将文件下载为“newname.mp3”,而不是“file.mp3”?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接