2012-02-14 107 views
2

是很常见的,它们位于公共文件夹外的PHP服务器下载的文件:服务下载文件用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. 与服务的静态文件比较网络服务器(直接文件URL);该方法是否需要更多资源(内存和CPU),因为PHP需要读取文件并交付?

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

回答

2

1既然你要处理与此脚本它需要更多的资源 不仅仅是正常的下载链接的文件。但这取决于您的需求。如果你认为这些文件需要更多的安全性。假设只有经过身份验证的用户才能下载该文件,并且只有该文件属于他。然后你需要验证那些。在这种情况下,你需要在你的问题中提供的代码。如果你的文件对公众开放,那么你可以显示文件的直接链接,可能暂时在公共场所找到它们。

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

方法1:

需要Javascript支持,以在方便的方式执行这种要求。假设您需要在可下载的页面上显示一些HTML。你可以用你想要的HTML创建一个页面,你可以放一个下载按钮。

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

而且你可以保持隐藏的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刷新为好。

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

你也可以用这个HTML显示。

+0

非常微妙的JS技巧! – Googlebot 2012-02-14 01:50:35

2
  1. 不是直接服务于该文件,因为你现在涉及PHP
  2. 没有稍多开销,你不能。如果你输出一个(比如说)应用程序/ msword头文件,那么你输出的所有东西都将被视为.doc文件的一部分,并导致它被破坏。如果你想输出一些文本,你必须做两部分下载 - 输出一个标准的HTML页面的文本,并包括定时<meta>(或JavaScript)重定向转发用户到实际的下载url。
3
  1. 是,读取文件用PHP和写入到一个用户会根据文件的大小是使用过程中的更多的内存和CPU。
  2. 首先显示一个页面,并在页面上有一个按钮/链接,让用户可以看到实际的下载脚本。

另外我会建议使用内容长度标题以及。

header('Content-Length: '. filesize($path)); 
+0

非常感谢关于'header'的信息。它拯救了我的日子 – 2015-06-19 06:49:26

1

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

所以要添加的东西已经给出了答案:

  • 完成时使用ob_end_flush()发送头,结束输出缓冲,因此该文件内容将不会在内存中开始输出
  • 之前被缓存
  • readfile()可能流从磁盘上的文件到网络更有效地比你的循环

有人说,但可以强调也不过分:包括Content-Length标题,因为它将允许下载程序测量进度。