【问题标题】:Issue while handling PNG image from MSSQL database处理来自 MSSQL 数据库的 PNG 图像时出现问题
【发布时间】:2017-08-21 16:05:39
【问题描述】:

我无法保存/查看存储在 MsSQL 数据库中的 PNG 文件,如下所示:

我正在使用下一个代码来获取文件:

function manualDIRECTimg(){
ini_set('mssql.textlimit', '100000000');
ini_set('mssql.timeout', '9999');
ini_set('mssql.compatability_mode', '1');
ini_set('mssql.textsize', '100000000');
set_time_limit(0);
header('Content-Type: image/png');

$codPRODUSerp = $_GET['id'];

$rowerp=mssql_fetch_array(mssql_query("EXECUTE spWEBSelectFoto ".$codPRODUSerp.", 1"));
$img=$rowerp['0'];  // The image is stored in column0

if($img!=''){

global $defaultPRODUCTimagePATH;
$imagineprodusTMP = $defaultPRODUCTimagePATH.'_0_TMPzz.jpg';

$file = fopen( $imagineprodusTMP, "w" );
fwrite( $file, $img);
fclose( $file);
readfile($imagineprodusTMP);
unlink($imagineprodusTMP);
}else{echo "There's no image found in the database";}

}

但输出是在 10% 后被“剪切”的图像......从 MsSQL 拉取 JPG 图像时不会发生这种行为......有什么想法吗?

我尝试过使用 while 循环,但最终会生成一个巨大的文件,可能是因为它一直处于循环状态,直到服务器端限制启动(脚本执行时间等)

while($rowerp=mssql_fetch_array(mssql_query("EXECUTE spWEBSelectFoto ".$codPRODUSerp.", 1"))){ echo $rowerp['0']; }  //with the appropiate headers...

即使我对 $img 字符串进行编码,尝试 PNG 图像时仍然得到相同的结果...https://pastebin.com/ce6ndFai

JPG/JPEG 图像再次正常...此问题仅发生在 PNG 上

附:实际文件如下: (一个好的拉取保存的JPEG图片)

(坏 PNG ...)

这不是原始(数据库)图像大小(以 kb 为单位)的问题,而是以像素为单位的大小,我有一个 500x500 像素的小图像和一个 1000x1000 像素的 PNG,它们的作用方式相同。我必须说,当使用它的实际软件正确输出时,存储的图像可以正常工作:

【问题讨论】:

  • 您在 SQL Server 中存储的字段的数据类型和长度是什么?
  • 很抱歉,您还得再帮我一些忙,我对 PHP-MSSQL 完全不熟悉……在我的案例中使用的 ERP 软件的开发人员给了我一套具有从 MS SQL 服务器中提取数据的函数的指令,在本例中为 EXECUTE spWEBSelectFoto ".$codPRODUSerp.", 1 ... 其中 codPRODUSerp 是唯一标识符,1 是一组 10 个图像中的第一个图像(在我的情况下仅使用文件 numer1)
  • 我不知道如何获取存储在单元格中的数据类型和长度,我使用Adminer 浏览 MySQL、MSSQL 服务器...虽然我保存了由PNG的管理员...如果它有帮助sql export(CSV,带有,作为分隔符)
  • 您可以在 SQL 服务器上运行以下命令并显示结果(不带引号)吗? "sp_helptext spWEBSelectFoto"
  • 发生这种情况是因为您的数据库堆栈无法处理超过 64K(2^16 字节)的数据;此时数据被切断。 JPEG 图像符合此限制,而 PNG 图像则不符合。至于究竟在哪里失败,我不能说。 mssql_* 函数很古老,并且依赖于更古老的访问库。试试Microsoft themselves提供的库。

标签: php sql-server


【解决方案1】:

您在这里遇到了几个问题,例如您使用了全局变量和已弃用的数据库函数,以及一种不必要的费力输出方法。以下是我的处理方法:

// database is passed as a parameter; assume it's PDO:
// $db = new PDO("mssql:host=db_host;dbname=db_name");
// ID is also passed to the function instead of using a global

function manualDIRECTimg($db, $id) {
    $sql    = "EXECUTE spWEBSelectFoto ?, 1";
    $params = array($id);
    $stmt   = $db->prepare($sql, $params);
    $stmt->exec();
    if ($img = $stmt->fetchColumn()) {
        // Are all of these images guaranteed to be PNG?
        // If not you'll need to adjust this as needed
        header("Content-Type: image/png");
        echo $img;
        return true;
    }    
    return false;
}

如果您的数据库获取一张图片的时间超过了默认的脚本超时时间, 与数据库管理员一起提出。用户不会为一张图片等待 60 秒,禁用超时不是一个合理的方法!

尽管如此,一定要抛弃那些旧的 mssql 函数。它们早已被弃用,甚至不存在于现代版本的 PHP 中。

【讨论】:

    【解决方案2】:

    这似乎是 SQL 服务器如何传递数据的问题,我设法对 miken32 的代码进行了一些更改并最终得到:

    function manualPDOdirectIMG() {
    set_time_limit(0);
    $codPRODUSerp = $_GET['id'];
    $db = new PDO("dblib:host=xxx.xxx.xxx.xxx;dbname=DATABASE", "USER", "PWD");
        $sql    = "EXECUTE spWEBSelectFoto ".$codPRODUSerp.", 1";
        $stmt   = $db->prepare($sql);
        $stmt->execute();
        if ($img = $stmt->fetchColumn()) {
            header("Content-Type: image/png");
            echo $img;
            return true;
        }    
        return false;
    }
    

    同样的“剪切”图像结果...

    感觉得到大家的帮助真是太棒了!

    就我的问题而言,答案是:

    在这种情况下,这是远程 MSSQL 配置错误的问题。

    【讨论】:

      【解决方案3】:

      一段时间后,我发现导致图像被截断的问题,在我最初的测试中,我使用了一个简单的

      ini_set('mssql.textlimit', '5242880'); ini_set('mssql.textsize', '5242880');

      这没有产生任何影响,因此传输的数据在 60KB 后被截断......经过一些研究我发现手动设置

      mssql_query("SET TEXTSIZE 5242880");

      在实际的 mssql_fetch_array 查询之前,解决了我的问题! 从而指示 MSSQL 将覆盖 TEXTLIMIT 和 TEXTSIZE 以确保 sql 和 php 之间的完整数据传输

      感谢大家的智慧!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-06-19
        • 1970-01-01
        • 2011-03-14
        • 2016-10-11
        • 1970-01-01
        • 2021-01-17
        • 1970-01-01
        相关资源
        最近更新 更多