使用 php 提供可下载文件

发布于 2025-01-06 01:29:52 字数 463 浏览 2 评论 0原文

PHP 服务器位于公共文件夹之外的可下载文件很常见:

$fp = fopen($file,"r") ;
header("Content-Type: application/msword");
header('Content-Disposition: attachment; filename="'.$filename.'"');

while (! feof($fp)) {
    $buff = fread($fp,4096);
    echo $buff;
}

我有两个问题:

  1. 与 Web 服务器提供的静态文件(直接文件 URL)进行比较;这种方法是否需要更多资源(内存和CPU),因为PHP需要读取文件并传递?

  2. 如何在页面上显示一些文本?正如我们定义的 header 一样,我们没有 php 脚本的 html 输出。

It is common to server downloadable files which are located outside the public folder by PHP:

$fp = fopen($file,"r") ;
header("Content-Type: application/msword");
header('Content-Disposition: attachment; filename="'.$filename.'"');

while (! feof($fp)) {
    $buff = fread($fp,4096);
    echo $buff;
}

I have two questions:

  1. Comparing with static files served by web server (direct file URL); does this method needs more resources (memory and cpu), as PHP needs to read the file and deliver?

  2. How we can display some text on the page? As we defined header, we do not have html output of the php script.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

请帮我爱他 2025-01-13 01:29:52
  1. 是的,使用 PHP 读取文件并将其写入用户将使用更多内存和 CPU,当然取决于文件有多大。
  2. 首先显示一个页面,并在页面上有一个按钮/链接,将用户带到实际的下载脚本。

另外我建议也使用内容长度标头。

header('Content-Length: '. filesize($path));
  1. Yes, reading a file with PHP and writing it to a user will use more memory and CPU, of course depending on how big the file is.
  2. Show a page first, and have a button/link on the page that takes the user to the actual download script.

Also I'd suggest using the Content Length Header as well.

header('Content-Length: '. filesize($path));
爱*していゐ 2025-01-13 01:29:52

1 由于您必须使用此脚本处理文件,因此需要更多
资源不仅仅是普通的下载链接。不过,这取决于您的需求。如果您认为这些文件需要更高的安全性。假设只有经过身份验证的用户才能下载该文件,并且只有该文件属于他。然后你需要验证这些。在这种情况下,您需要在问题中输入的代码。如果您的文件向公众开放,那么您可以显示该文件的直接链接,可能会暂时将它们定位在公共的某个地方。

2 我可以建议您使用两种方法来执行此操作。

方法1:

您需要javascript支持才能方便地执行此类需求。假设您需要在可以下载的页面上显示一些 HTML。您可以使用所需的 HTML 创建一个页面,并且可以放置一个下载按钮。

并且您可以保留隐藏的 iframe 来处理下载。

<iframe id="downloadFrame" style="display:none"></iframe>

假设您的 PHP 下载页面是 download.php。

然后你就可以有一个像这样的javascript函数。

<script type="text/javascript">
function downloadFile(filepath) 
{
    var ifrme = document.getElementById("downloadFrame");
    ifrme.src = "download.php?filepath="+filepath;
}
</script>

方法2:

除了上述方法之外,您还可以使用META Refresh。

<meta http-equiv="Refresh" content="3;URL=<?php echo $fullHTTPathToYourFile ?>" />

你也可以用它来显示 HTML。

1 Since you have to process the file with this script it require more
resources than just normal download link. However this is depend on your needs. If you think these files need more security. Let's say only authenticated users can download the file and only the file belongs to him. Then you need to validate those. In such situation you need the code you have put in your question. If your files are open to the public then you can display direct link to the file may be locating them somewhere in public temporarily.

2 I can suggest you two methods to perform this.

Method 1 :

You need javascript support to perform this kind of requirement in handy way. Assume you need to display some HTML on the page where the download is possible. You can create a page with the HTML you want and you can put a download button.

<input type="button" name="cmdDownload" id="cmdDownload" value="Download" onclick="downloadFile('<?php echo $pathToTheFile; ?>');" />

And you can keep hidden iframe to process the download.

<iframe id="downloadFrame" style="display:none"></iframe>

Assume your PHP download page is download.php.

Then you can have a javascript function like this.

<script type="text/javascript">
function downloadFile(filepath) 
{
    var ifrme = document.getElementById("downloadFrame");
    ifrme.src = "download.php?filepath="+filepath;
}
</script>

Method 2:

Other than above method you can use META Refresh as well.

<meta http-equiv="Refresh" content="3;URL=<?php echo $fullHTTPathToYourFile ?>" />

You can have HTML display with this too.

国产ˉ祖宗 2025-01-13 01:29:52
  1. 比直接提供文件的开销稍大一些,因为您现在涉及 PHP
  2. 不,您不能。如果您输出(例如)application/msword 标头,那么您输出的任何内容都将被视为 .doc 文件的一部分,并导致其损坏。如果您想输出一些文本,则必须分两部分进行下载 - 输出包含文本的标准 HTML 页面,并包含定时 (或 javascript)重定向以转发用户到实际的下载网址。
  1. Slightly more overhead than serving up the file directly, since you're now involving PHP
  2. No, you cannot. If you output a (say) application/msword header, then ANYTHING you output AT ALL will be considered part of the .doc file and cause it to become corrupted. If you want to output some text, you have to do the download in two parts - output a standard HTML page with the text, and include a timed <meta> (or javascript) redirect to forward the user to the actual download url.
慕巷 2025-01-13 01:29:52

如果输出缓冲处于活动状态,使用 PHP 提供文件将消耗大量内存,并且性能将比 apache 提供的常规文件差很多。

因此,要在已经给出的答案中添加一些内容:

  • 完成发送标头后,使用 ob_end_flush() 结束输出缓冲,因此在开始输出之前文件内容不会缓存在内存中
  • readfile()< /code> 可能比循环更有效地将文件从磁盘流式传输到网络

有人说过,但强调得不够:包含 Content-Length 标头,因为它将允许下载者测量进度。

If output buffering is active, serving a file using PHP will consume a lot of memory, and performance will be much worse than in the case of regular files served by apache.

So to add something to the answers already given:

  • when done sending headers, end output buffering using ob_end_flush(), so the file contents will not be cached in memory before starting output
  • readfile() might stream a file from disk to the web more efficiently than your loop

It has been said but cannot be stressed enough: do include the Content-Length header, since it will allow the downloader to measure progress.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文