我认为这应该很容易。我有一个分页图像库,每个图像下面都有一个小的链接,上面写着“Download Comp”。这应该允许人们快速将.jpg文件(带有PHP生成的水印)下载到他们的计算机上。
现在,我知道我可以直接链接到.jpg文件,但这需要用户在新窗口中打开图像,右键单击,另存为...等等。相反,我想要“下载Comp“链接以立即开始下载文件。
PHP.net似乎建议使用readfile(),因此每个“Download Comp”链接都被回显为“?download = true& g = {$ gallery}& i = {$ image}”。
然后在页面顶部我会看到$ _GET ['download'] var是否设置,如果是,我运行以下代码:
if(isset($_GET['download'])) {
$gallery = $_GET['g'];
$image = $_GET['i'];
$file = "../watermark.php?src={$gallery}/images/{$image}";
header('Content-Description: File Transfer');
header('Content-Type: application/jpeg');
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: public');
header('Pragma: public');
header('Content-Length: ' . filesize($file));
ob_clean();
flush();
readfile($file);
}
该链接需要一个lonnnnnnnnng时间,然后会弹出一个对话框提示,要求您打开或保存文件,但是一旦保存并尝试打开它,它就说文件已损坏且无法打开。
有什么想法吗?
答案 0 :(得分:4)
不要将$ file设置为相对网址。 readfile函数将尝试访问服务器上的php文件。那不是你想要的。在你的情况下,看起来watermark.php文件将发送你想要的内容,所以你可以设置它所需的环境并包含它。
<?php
if(isset($_GET['download'])) {
$gallery = $_GET['g'];
$image = $_GET['i'];
$_GET['src'] = "{$gallery}/images/{$image}";
header('Content-Description: File Transfer');
header('Content-Type: image/jpeg');
header('Content-Disposition: attachment; filename='.basename($image));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: public');
header('Pragma: public');
ob_clean();
include('../watermark.php');
exit;
}
另一种(更简单的)方法是修改watermark.php。添加一个查询参数,使其发送正确的标题以强制下载并链接到该
<a href="watermark.php?src=filename.jpg&download=true)">...</a>
watermark.php:
<?php
if (isset($_GET['download']) && $_GET['download'] == 'true') {
header('Content-Description: File Transfer');
header('Content-Type: image/jpeg');
header('Content-Disposition: attachment; filename='.basename($src));
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: public');
header('Pragma: public');
}
// continue with the rest of the file as-is
此外,您不需要调用flush()。此时不应发送任何输出,因此没有必要。
答案 1 :(得分:1)
header('Content-Type: image/jpeg');
也许?
答案 2 :(得分:1)
这似乎是一个安全问题。
如果有人进入该怎么办?
$g = '../../../../../../';
$i = '../../sensitive file at root';
如何制作.htaccess(如果你使用的是apache)我为gallery目录提供jpegs作为下载而不是正常。
答案 3 :(得分:0)
我认为您可能需要通过调用readfile()
来跟随对exit()
的调用,以确保没有其他内容写入输出缓冲区。
答案 4 :(得分:0)
另外,请尝试file_get_contents()
而不是readfile()
。我发现它在更多情况下有效。我还建议您在输出图像数据后使用ob_flush()
。我从来不需要使用ob_clean()
或flush()
来使这种事情发挥作用。
正如埃里克所说的那样,你可能也希望在那里打电话给exit()
,如果它仍然无法正常工作,以防万一你最后收到一些垃圾数据。