PHP 文件传输 - 这是如何工作的?

PHP File Transfer - How does this work?

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

$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 行来实现我的目的:

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

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

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

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

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

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

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

readfile(realpath($cf));

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

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

Is the purpose of using basename() simply to strip the path from the filename?

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

What is the purpose of realpath()? In my usage, it seems to make no difference whatsoever. Based on what I've found, it seems to just 'standardize' filepath inputs. Is that correct?

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

I don't seem to need the last three lines to make this work:

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

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

readfile(realpath($cf));

Do I need them? What do they do? I should note that I'm testing just using localhost, in case that makes a difference.

你应该把它们都留着。前两个 header 告诉浏览器文件有多大以及文件的类型。现在您使用的是通用媒体类型,但如果您要发送 PDF 文件,则可以使用 more-specific PDF 媒体类型,浏览器会让用户知道他们正在下载 PDF。

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