0

在我的函数中,我保存了从 base64 字符串解码的图像:

function saveImage(){
    //magic...
    define('UPLOAD_DIR', '../webroot/img/');
    $base64string = str_replace('data:image/png;base64,', '', $base64string);
    $base64string = str_replace(' ', '+', $base64string);
    $data = base64_decode($base64string);
    $id = uniqid();
    $file = UPLOAD_DIR.$id.'.png';
    $success = file_put_contents($file, $data);
}

上述功能正常工作,图像保存在指定文件夹中且未损坏。

在下一个函数中,我现在尝试将图像强制下载给用户:

function getChart($uniqid= null){
    if($uniqid){
        $this->layout = null;
        header("Content-type: image/png");
        header("Content-Disposition:attachment;filename='".$uniqid.".png'");
        readfile('../webroot/img/'.$uniqid.'.png');
        exit;
    } else exit;
}

从服务器下载的图像已损坏,无法显示。在文本编辑器中打开下载的文件后,我注意到在最顶部添加了一个换行符。删除字符并保存文件后,它会正确打开并正确显示。

我怎样才能解决这个问题?

4

6 回答 6

1
header("Content-length: $file_size")

此标头告诉浏览器文件有多大。某些浏览器需要它才能正确下载文件。无论如何,这是一个很好的方式来告诉文件有多大。这样,任何下载文件的人都可以预测下载需要多长时间。

header("Content-type: $file_type")

这个标头告诉浏览器它试图下载什么样的文件。

header("Content-Disposition: attachment; filename=$file_name");

这告诉浏览器以指定的名称保存这个下载的文件。如果您不发送此标头,浏览器将尝试使用脚本名称保存文件。

但是您需要在第一个出口的正上方flush();或在您的情况下刷新缓冲区;ob_flush();

于 2012-09-28T12:03:30.280 回答
1

在您实际打开下载的文件之前,您所描述的内容可能会隐藏多个问题。

而是使您的代码更健壮并检查先决条件,如果标头已经发送并清理任何可能的现有输出缓冲区并在不可能的情况下给出错误:

function getChart ($uniqid = null) {

    if (!$uniqid) exit;

    $this->layout = null;

    if (headers_sent()) throw new Exception('Headers sent.');
    while (ob_get_level() && ob_end_clean());
    if (ob_get_level()) throw new Exception('Buffering is still active.');

    header("Content-type: image/png");
    header("Content-Disposition:attachment;filename='".$uniqid.".png'");
    readfile('../webroot/img/'.$uniqid.'.png');

    exit;
}
于 2012-09-28T12:07:20.333 回答
0

在调用之前检查您是否正在输出某些内容readfile

// add ob_start() at the very top of your script
function getChart($uniqid= null){
    echo strlen(ob_get_clean()); die(); // if it's not 0 then you are definetly echoing something

    if($uniqid){
        $this->layout = null;
        header("Content-type: image/png");
        header("Content-Disposition:attachment;filename='".$uniqid.".png'");
        readfile('../webroot/img/'.$uniqid.'.png');
        exit;
    } else exit;
}
于 2012-09-28T12:03:49.030 回答
0

编辑(强制下载):

function getChart($uniqid= null){
    if($uniqid){

        $image = $uniqid;

        header("Cache-Control: public");
        header("Content-Description: File Transfer");
        header("Content-Disposition: attachment; filename=" . $image);
        header("Content-Type: image/jpg");
        header("Content-Transfer-Encoding: binary");

        readfile($image);

    } else exit;
}

getChart("060620121945.jpg");

试试这个(只是为了渲染图像):

function getChart($uniqid= null){
    if($uniqid){

        $mime_type = "image/png";
        $content = file_get_contents('../webroot/img/'.$uniqid.'.png');
        $base64   = base64_encode($content); 
        return ('data:' . $mime_type . ';base64,' . $base64);

    } else exit;
}
于 2012-09-28T12:01:55.787 回答
0

我曾多次遇到这个问题。这是我使用的解决方案:

结果几乎总是我忘记关闭文件中的unicode BOM编码,download.php这会在下载文件的前面添加一些内容,因此会损坏它。

所以解决办法关掉unicode BOMdownload.php

于 2015-06-14T16:23:07.947 回答
0

只需使用 ob_clean(); 在 readfile() 之前

于 2017-08-16T22:16:08.777 回答