使用PHP为.jpg文件创建下载链接

时间:2009-10-13 19:47:11

标签: php file download hyperlink

我认为这应该很容易。我有一个分页图像库,每个图像下面都有一个小的链接,上面写着“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时间,然后会弹出一个对话框提示,要求您打开或保存文件,但是一旦保存并尝试打开它,它就说文件已损坏且无法打开。

有什么想法吗?

5 个答案:

答案 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(),如果它仍然无法正常工作,以防万一你最后收到一些垃圾数据。