【问题标题】:PHP File Transfer - How does this work?PHP 文件传输 - 这是如何工作的?
【发布时间】:2016-07-29 17:14:55
【问题描述】:

所以,在另一个QUESTION,我得到了这个答案:

$filename="filetodownload.xyz";
$cf = realpath("/non-webaccessible-folder/".$filename);
$file=$cf;

header('Content-Disposition: attachment; filename="' . basename($cf) . '"');
header("Content-Length: " . filesize($cf));
header("Content-Type: application/octet-stream");
readfile(realpath($cf));

只需使用顶部标题行,我就能让它为我的目的工作:

header('Content-Disposition: attachment; filename="' . basename($cf) . '"');

我对整个解决方案有一些疑问,以增加我的理解:

1. 使用basename() 的目的仅仅是为了从文件名中去除路径吗?

2.realpath()的目的是什么?在我的使用中,它似乎没有任何区别。根据我的发现,它似乎只是“标准化”文件路径输入。对吗?

3.我似乎不需要最后三行来完成这项工作:

header("Content-Length: " . filesize($cf));

header("Content-Type: application/octet-stream");

readfile(realpath($cf));

我需要它们吗?他们在做什么?我应该注意,我只是使用 localhost 进行测试,以防万一。

在使用这种方法提供文件下载时,我应该注意哪些安全问题?

【问题讨论】:

  • For 3 是让浏览器知道文件有多大,以便用户可以看到。否则它会显示为 downloaded 1mb of unknown filesize
  • 使用真实路径的原因有很多。对于这种情况下的答案,我使用它作为包含该文件的文件夹的路径是 Windows 服务器上的虚拟目录。如果没有 realpath,file_exists 和其他功能似乎无法可靠地工作。一旦我使用了 realpath,脚本就会按预期运行。这是我当时从另一个地方找到的建议。

标签: php linux apache download file-transfer


【解决方案1】:

使用 basename() 的目的只是为了从 文件名?

是的,浏览器使用此标头向用户显示文件名,以将下载的文件另存为。您不想为用户提供完整的文件路径,只提供文件名,而且我不确定浏览器是否会向用户提供完整的文件路径。

realpath() 的目的是什么?在我的使用中,它似乎没有 有什么区别。根据我的发现,它似乎只是 “标准化”文件路径输入。对吗?

它将相对链接和符号链接解析为其绝对路径,这可能就是您所说的“标准化”。如果你只提供绝对路径,它什么也不做。

我似乎不需要最后三行来完成这项工作:

header("内容长度:" .filesize($cf));

header("Content-Type: application/octet-stream");

读取文件(真实路径($cf));

我需要它们吗?他们在做什么?我应该注意我只是在测试 使用 localhost,以防万一。

您应该保留它们。前两个标题告诉浏览器文件有多大以及它是什么类型的文件。现在您使用的是通用媒体类型,但如果您要发送 PDF 文件,您可以使用更具体的 PDF 媒体类型,并且浏览器会让用户知道他们正在下载 PDF。

我也不认为没有最后一行就无法下载...这就是 PHP 实际读取文件并将其发送到浏览器的内容。如果你忽略它,你最终可能会下载一个空白文件。

【讨论】:

  • 感谢您的信息。事实证明,我确实需要 readfile。正如您所怀疑的,省略它会导致下载一个空文件。但是,我似乎并不真的需要其他两个标题(我只会传输 .zip),但我会按照您的建议将它们保留。我已经打开了与此相关的ANOTHER QUESTION
猜你喜欢
  • 2013-01-18
  • 1970-01-01
  • 2015-03-10
  • 2011-11-07
  • 1970-01-01
  • 2015-12-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多