3

我需要使用fpdf库创建一个 pdf 文件并将其保存在我的 MySQL 数据库中的 blob 字段中。问题是,当我尝试从 blob 字段中检索文件并将其发送到浏览器进行下载时,下载的文件已损坏并且无法正确显示。

如果我立即将其发送到浏览器而不将其存储在数据库中,则可以正确显示相同的 pdf 文件,因此似乎某些数据在插入数据库时​​已损坏。

我的代码是这样的:

$pdf = new MyPDF(); //class that extends FPDF and create te pdf file
$content = $pdf->Output("", "S"); //return the pdf file content as string
$sql = "insert into mytable(myblobfield) values('".addslashes($content)."')";
mysql_query($sql);

存储pdf,像这样:

$sql = "select myblobfield from mytable where id = '1'";
$result = mysql_query($sql);
$rs = mysql_fetch_assoc($result);
$content = stripslashes($rs['myblobfield']);
header('Content-Type: application/pdf');
header("Content-Length: ".strlen(content));
header('Content-Disposition: attachment; filename=myfile.pdf');
print $content;

将其发送到浏览器进行下载。我究竟做错了什么?

如果我将代码更改为:

$pdf = new MyPDF(); 
$pdf->Output(); //send the pdf to the browser

该文件已正确显示,因此我认为该文件已正确生成并且问题出在数据库中的存储中。

提前致谢。

4

6 回答 6

3

实际上出于安全原因:

  1. 不要使用addslashes(),而是mysql_real_escape_string()使用

在这种特定情况下(因为它是二进制数据):

  1. 消除stripslashes()
  2. 替换addslashes()mysql_real_escape_string()
于 2009-08-20T15:50:31.870 回答
2

您不应该剥离任何(反)斜杠。添加它们时,它们在查询中用作转义字符,不会出现在字段中。

尝试改变这个

$content = stripslashes($rs['myblobfield']);

进入这个:

$content = $rs['myblobfield'];
于 2009-08-20T15:38:33.580 回答
1

比较字符串中的差异以帮助调试问题。

$pdf = new MyPDF();
echo $pdf->Output("", "S"); //send the pdf string to the browser
exit;

$pdf = new MyPDF(); //class that extends FPDF and create te pdf file
$content = $pdf->Output("", "S"); //return the pdf file content as string
$sql = "insert into mytable(myblobfield) values('".addslashes($content)."')";
mysql_query($sql);
$sql = "select myblobfield from mytable where id = '1'";
$result = mysql_query($sql);
$rs = mysql_fetch_assoc($result);
$content = stripslashes($rs['myblobfield']);
echo $content; //send the pdf string to the browser
exit;
于 2009-08-20T15:43:50.807 回答
1

更换

header("Content-Length: ".strlen(content)); 

header("Content-Length: ".strlen($content)); 

为我工作。

于 2010-11-13T03:17:15.930 回答
0

解决了!

我也遇到了同样的问题,正在尝试上述想法。为我解决这个问题的是我的 MySQL 数据库将 PDF 存储为 ablob而不是mediumblob. 一个 blob 字段被限制为 64K,从而截断了我的 PDF 的其余部分,其中包括有价值的数据,包括 EOF(因此是讨厌的 Adob​​e 错误)。

要确认,请下载它提供的 PDF 文件,然后查看文件大小。如果它恰好是 64K,则需要通过将字段设置为mediumblob.

感谢大家的帮助!

顺便说一句,我听从了 Toto 的建议,mysql_real_escape_string()改用了:

  1. 消除stripslashes()
  2. 替换addslashes()mysql_real_escape_string()

随着对原始海报代码的这些更改,它起作用了!

于 2010-07-12T01:44:17.663 回答
0

我最近正在处理这个问题,在我们给出测试解决方案后给出答案很重要。然后,我解决了这个问题如下。为了保存生成的 fpdf,我使用了这个代码..

$content = $pdf->Output("", "S"); 
// addslashes is the key to store blob file
$data = addslashes($content); 
$name = "testname.pdf";
$mime = "application/pdf";
$extficheiro = "pdf";
$nomeficheiro = "miarchivo";
$size = strlen($content);
$query = "INSERT INTO filetable(name, mime, size, data, created)
    VALUES ('$name','$mime', '$size', '$data', NOW())";                      
$conn->query($query);

从我的数据库中读取(从数据库中检索)比我使用 pdo 代码更可取:

if(filter_has_var(INPUT_GET, "var") !== false && filter_input(INPUT_GET, 'var', FILTER_VALIDATE_INT) !== false)
{
    $var = filter_input(INPUT_GET, "var", FILTER_SANITIZE_NUMBER_INT);
    try     {
        $dbh = new PDO("mysql:host=our_host;dbname=database", 'username', 'password');
        $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

        $sql = "SELECT * FROM filetable  WHERE id= ".$var;

        $stmt = $dbh->prepare($sql);
        $stmt->execute(); 
        $stmt->setFetchMode(PDO::FETCH_ASSOC);
        $array = $stmt->fetch();

        /*** set the headers and display the file ***/
        header("Content-Type: ". $array['mime']);
        header("Content-Length: ". $array['size']);/**/
        header("Content-Disposition: inline; filename='". ($array['name'])."'");
        echo $array['data'];
    }
    catch(PDOException $e)
    {
        echo $e->getMessage();
    }
    catch(Exception $e)
    {
        echo $e->getMessage();
    }
}
else
{
    echo '0'; // out of bounds
}

这些代码运行良好。我希望这个贡献可以帮助其他人解决这个问题。最好的祝福。

于 2016-11-17T11:57:12.977 回答