我试图制作一个脚本来从我的localhost下载图像。仅适用于学校项目。
我通过url获取文件名(“$ _GET ['file']”)。然后我运行这个脚本。每次文件损坏,无法查看。我想下载图像,但是当我尝试word文档时它也被损坏了。这是我的代码:
<?php
//get file
$file = $_GET['file'];
//set path of file
$path = $_SERVER['DOCUMENT_ROOT']."/blackbox/mediafiles/";
$fullPath = $path.$file;
if ($fd = fopen ($fullPath, "r")) {
$path_parts = pathinfo($fullPath);
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // fore a download
header("Content-type: application/octet-stream");
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
}
header("Cache-control: private"); // open files directly
while(!feof($fd)) {
$buffer = fread($fd, 2048);
echo $buffer;
}
fclose ($fd);
exit;
?>
有人知道出了什么问题吗?
提前致谢!!
答案 0 :(得分:3)
尝试以二进制模式显式打开文件:
if ($fd = fopen ($fullPath, "rb")) {
正如fopen所述的文档所述:
Windows提供了一个文本模式转换标志('t') 在处理文件时透明地将\ n转换为\ r \ n。在 相比之下,您也可以使用'b'来强制二进制模式,而不是 翻译您的数据。要使用这些标志,请指定“b”或“t” 模式参数的最后一个字符。
默认转换模式取决于SAPI和PHP版本 您正在使用,因此我们鼓励您始终指定 出于便携性原因的适当标志。你应该使用't'模式 如果您正在使用纯文本文件,并使用\ n来分隔 您的行结尾在您的脚本中,但希望您的文件可读 与记事本等应用程序。你应该在所有其他人中使用'b' 例。
如果在处理二进制文件时没有指定'b'标志,那么 您的数据可能会遇到奇怪的问题,包括图像损坏 文件和\ r \ n字符的奇怪问题。
答案 1 :(得分:1)
您可以使用readfile代替手动阅读文件和输出。
此外,请注意,$ _GET ['file']可以包含'../'并打开任何文件,这是一个安全风险。使用basename功能(如果所有文件都在同一目录中)或限制访问mediafiles目录之外的文件
<?php
//get file
$file = $_GET['file'];
//set path of file
$path = $_SERVER['DOCUMENT_ROOT']."/blackbox/mediafiles/";
$fullPath = $path. basename($file);
if (is_readable($fullPath) {
$path_parts = pathinfo($fullPath);
header("Content-Disposition: attachment; filename=\"".$path_parts["basename"]."\""); // fore a download
header("Content-type: application/octet-stream");
header("Content-length: " . filesize($fullPath));
header("Content-Disposition: filename=\"".$path_parts["basename"]."\"");
header("Cache-control: private"); // open files directly
readfile($fullPath);
}
exit;
?>
答案 2 :(得分:1)
要么某些东西从PHP中抛出错误,要么在文件中的开始标记之前有前导空格(<?php
)。
做两件事:
<
的{{1}} 是文件中的第一个字符。确保您的脚本中没有字节顺序标记。<?php
请注意,如果禁用错误修复了您的问题,则表示存在需要修复的错误,这不是问题的最终解决方案!
使用readfile()
也比打开文件指针并循环它更短,更安全,更有效。
答案 3 :(得分:1)
起初它不是你的答案。但你应该真的看看PHP中的安全性。在您的脚本上,您可以通过GET参数和DOCUMENT_ROOT访问所有文件。
不要相信用户。
您应首先过滤变量,或在将变量传递给用户之前将其映射到已知的文件列表。