图像下载 - 图像无法打开

时间:2011-09-29 08:06:59

标签: php

我尝试创建一些代码,以便用户可以在没有右键单击并使用Save as...的情况下在opencart中下载图像,但在我创建此代码并下载图像后,尝试打开图像说图像已损坏

<form action="download.php" method="post" >
<input type="text" name="file" value="<?php echo $image['popup']; ?>" />
<input type="submit" value="download" />
</form>

的download.php

<?php
$file= $_POST["file"];

header ("Cache-Control: must-revalidate, post-check=0, pre-check=0");
header ("Content-Type: application/octet-stream");
header('Content-Disposition: attachment; filename='.basename($file));
header('Content-type: application/pdf');
header('Content-type: image/jpg');
header('Content-type: image/gif');
header('Content-type: image/png');

readfile('$file');

?>

4 个答案:

答案 0 :(得分:3)

您当前的问题是,当使用单引号时,$file将不会被解析,而是按字面意思理解。使用双引号或无引号:

readfile($file);

其他观察:

  • 为什么要发送五种不同的内容类型?这没有意义。您应该检测文件的类型并发送相应的图像标题(如果您只想提供可下载的资源,则只发送application/octet-stream,而不是尝试在浏览器中显示它。)

  • 您应该检查$file是否实际指向您要允许下载的文件之一。如果没有检查,攻击者就可以通过这种方式从您的站点获取任何文件,包括配置文件。

答案 1 :(得分:0)

您无法多次定义内容类型。通过文件扩展名确定内容类型,并包含正确的内容类型。

除此之外,请使用:

readfile($file);

不需要报价。编辑:使用引号它甚至不起作用,但它会尝试打开名为$ file

的文件名

答案 2 :(得分:0)

您发送了多个Content-Type标头?这是错的。

您必须通过文件的扩展名(.jpg,.pdf,...)确定Content-Type,然后发送相应的标题。

以下是我最近完成的下载脚本片段。

    $fileName   = $_POST['file']; // or whatever
    $file       = 'someDirectory/' . $fileName; // full path of the file, could also be absolute
    $fileLen    = filesize($file);          
    $ext        = strtolower(substr(strrchr($fileName, '.'), 1));

    switch($ext) {
        case 'txt':
            $cType = 'text/plain'; 
        break;              
        case 'pdf':
            $cType = 'application/pdf'; 
        break;
        case 'exe':
            $cType = 'application/octet-stream';
        break;
        case 'zip':
            $cType = 'application/zip';
        break;
        case 'doc':
            $cType = 'application/msword';
        break;
        case 'xls':
            $cType = 'application/vnd.ms-excel';
        break;
        case 'ppt':
            $cType = 'application/vnd.ms-powerpoint';
        break;
        case 'gif':
            $cType = 'image/gif';
        break;
        case 'png':
            $cType = 'image/png';
        break;
        case 'jpeg':
        case 'jpg':
            $cType = 'image/jpg';
        break;
        case 'mp3':
            $cType = 'audio/mpeg';
        break;
        case 'wav':
            $cType = 'audio/x-wav';
        break;
        case 'mpeg':
        case 'mpg':
        case 'mpe':
            $cType = 'video/mpeg';
        break;
        case 'mov':
            $cType = 'video/quicktime';
        break;
        case 'avi':
            $cType = 'video/x-msvideo';
        break;

        //forbidden filetypes
        case 'inc':
        case 'conf':
        case 'sql':                 
        case 'cgi':
        case 'htaccess':
        case 'php':
        case 'php3':
        case 'php4':                        
        case 'php5':
        exit;

        default:
            $cType = 'application/force-download';
        break;
    }

    $headers = array(
        'Pragma'                    => 'public', 
        'Expires'                   => 0, 
        'Cache-Control'             => 'must-revalidate, post-check=0, pre-check=0',
        'Cache-Control'             => 'public',
        'Content-Description'       => 'File Transfer',
        'Content-Type'              => $cType,
        'Content-Disposition'       => 'attachment; filename="'. $fileName .'"',
        'Content-Transfer-Encoding' => 'binary', 
        'Content-Length'            => $fileLen         
    );

    foreach($headers as $header => $data)
        header($header . ': ' . $data); 

    @readfile($file);  

答案 3 :(得分:0)

        $mimeInfo = finfo_open(FILEINFO_MIME_TYPE); 
        $mime_type = finfo_file($mimeInfo, $_FILES['files']['tmp_name']);

将帮助您检测与

一起使用的mimetype
        header('Content-Type: '.$this->_mime_type);
        header('Content-Disposition: attachment; filename='.basename($file));
        header('Content-Transfer-Encoding: binary');
        header('Expires: 0');
        header('Cache-Control: must-revalidate');
        header('Pragma: public');
        header('Content-Length: ' . filesize($file));