【问题标题】:Protecting / serving a file via readfile(), force download?通过 readfile() 保护/提供文件,强制下载?
【发布时间】:2012-09-19 17:16:30
【问题描述】:

我正在尝试制作一个简单的脚本来做两件事:

  1. 提供一个文件并隐藏它的目的地
  2. 有下载计数器

现在,我在 wordpress 环境中执行此操作,但这个问题并不完全与 wordpress 相关,所以我想我会在这里问。

基本上,我目前设置它的方式是我有一个链接,当您单击它时会设置一个$_['GET'],然后检查它是否已设置。如果已设置,则提供下载文件。

链接:<a href="http://localhost:8888/fresh/?dl_id=01">Click here!</a>'

$_['GET'] 代码:http://pastebin.com/93nD43gA

代码中有一点 wordpress 行话,但基本上是检查下载计数 user_meta,如果 > 0,则调用 serveFile()

我在这里遇到的主要问题是,如果我单击链接,readfile() 会将实际文件内容加载到窗口中(乱码文本)。如果我将target=_blank 添加到<a>,它将打开一个新的浏览器窗口并将内容加载到窗口中。

当我将它作为独立的 php 文件执行时,这种方法似乎工作得很好。我的主要问题是我需要保留 wordpress 空间,以便我可以调用与之关联的函数等。

我尝试在 self 页面、带有自定义模板的另一个页面(上面的 pastebin 中的代码)以及独立的 php 文件中使用 $_['GET']。前两个选项都将文件加载到窗口中。第三个不保留 wordpress 功能,即使我包含 blog-header.php

谁能指出如何让文件强制下载而不加载到窗口中的正确方向?

【问题讨论】:

    标签: php wordpress readfile force-download


    【解决方案1】:

    您需要为任何文件类型设置适当的标题。例如,如果readfile 始终提供 PDF,则应该这样做:

    // disable browser caching -- the server may be doing this on its own
    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    
    header('Content-Type: application/pdf');
    //forces a download
    header("Content-Type: application/force-download");
    header('Content-Disposition: attachment; filename=filename.pdf');
    readfile($file);
    

    请记住,header 仅在您未在请求中发送任何数据(包括空格)时才有效。

    【讨论】:

    • 感谢您的快速回复。我想知道这是否是问题所在。我会看看这个并报告。
    • 我目前正在提供 rar。它与带有独立 php 文件的 octet-stream(也尝试过 x-rar-compressed)一起工作得很好。但是,如果我尝试在 Wordpress 中做同样的事情,它会输出到网站的正文中。我无法从 Wordpress 中链接到另一个页面、同一页面或独立的 php 文件并获取文件以强制 dl。我读到也许设置一些 .htaccess 的东西可能会有所帮助。我很茫然。
    • @tr3online 查看注释掉readfile 的页面输出。有输出吗?还要查看发送的标头。
    • 这肯定与 wordpress 发送标题有关。我的独立 php 与 $_GET['dl_id'] = 1. When I try to include require('./wp-blog-header.php');` 我得到一个 Error 6 (net::ERR_FILE_NOT_FOUND) 完全正常工作。如果我尝试在另一个 WP 页面上包含 $_GET/force,我会得到 Warning: Cannot modify header information 并且文件输出到正文。我一生都无法弄清楚如何使这项工作。感谢迄今为止的帮助
    【解决方案2】:

    “乱码”文本是您想要的,但除此之外您还必须设置一个 mime。这可以通过简单地设置一个标题来完成,例如header("Content-Type: image/png");

    如果文件 mime 会有所不同(例如 pdf、doc、png 等),您应该查看 finfo 扩展名。有了它,您可以获得完整且正确的文件mime

    <?php
    $finfo = new \finfo(FILEINFO_MIME);
    $mime = $finfo->file('path/to/file', FILEINFO_MIME_TYPE);
    header("Content-Type: $mime");
    

    如前所述 - 只有在没有写入输出的情况下才能设置标头(没有回显、打印等。Output buffering 可以在这里为您提供帮助)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多