将使用 FPDF php 库创建的 PDF 保存在 MySQL blob 字段中

发布于 2024-08-02 06:04:48 字数 1115 浏览 9 评论 0原文

我需要使用 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

文件正确显示,所以我假设该文件已正确生成,问题出在数据库中的存储中。

提前致谢。

I need to create a pdf file with the fpdf library and save it in a blob field in my MySQL database.
The problem is, when I try to retrieve the file from the blob field and send it to the browser for the download, the donwloaded file is corrupted and does not display correctly.

The same pdf file is correctly displayed if I send it immediately to the browser without storing it in the db, so it seems some of the data gets corrupted when is inserted in the db.

My code is something like this:

$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);

to store the pdf, and like this:

$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;

to send it to the browser for downloading.
What am I doing wrong?

If I change my code to:

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

the file is correctly displayed, so I assume that is correctly generated and the problem is in the storing in the db.

Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

画尸师 2024-08-09 06:04:48

实际上出于安全原因:

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

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

  1. 删除 stripslashes()
  2. addslashes() 替换为 mysql_real_escape_string()

Actually for security reasons:

  1. Do not use addslashes() but use mysql_real_escape_string() instead

In this specific case (as it is binary data):

  1. Remove stripslashes()
  2. Replace addslashes() by mysql_real_escape_string()
忆离笙 2024-08-09 06:04:48

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

尝试将其更改

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

为:

$content = $rs['myblobfield'];

You shouldn't strip any (back)slashes. When you add them, they are used as escape characters in the query and do not appear in the field.

Try changing this

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

into this:

$content = $rs['myblobfield'];
紫瑟鸿黎 2024-08-09 06:04:48

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

$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;

Compare the differences in the strings to help debug the problem.

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

and

$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;
妥活 2024-08-09 06:04:48

替换

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

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

对我有用。

Replacing

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

with

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

worked for me.

落花随流水 2024-08-09 06:04:48

解决了!

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

要进行确认,请下载其提供的 PDF 文件并查看文件大小。如果正好是 64K,您需要通过将该字段设置为 mediumblob 来在数据库中腾出更多空间。

感谢大家的帮助!

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

  1. 删除 stripslashes()
  2. addslashes() 替换为 mysql_real_escape_string()

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

SOLVED IT!

I too was having the same problem and was trying the above mentioned ideas. What fixed this for me was that my MySQL database was storing the PDF as a blob instead of mediumblob. A blob field is limited to 64K and was thereby truncating the rest of my PDF which included the valuable data including EOF (hence the nasty Adobe Error).

To confirm, download the PDF file it serves up instead and look at the file size. If it's exactly 64K you'll need to make more room in the DB by setting the field to mediumblob.

Thanks everyone for the help!

By the way, I followed Toto's advice and used mysql_real_escape_string() instead, along with:

  1. Remove stripslashes()
  2. Replace addslashes() by mysql_real_escape_string()

With those changes to the original poster's code it worked!

青丝拂面 2024-08-09 06:04:48

我最近正在解决这个问题,在我们给出的测试解决方案之后给出答案很重要。然后,我按如下方式解决了这个问题。 为了保存生成的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
}

这些代码工作得很好。我希望这个贡献可以帮助其他人摆脱这个问题带来的头痛。此致。

I was recently working with this problem and it is important to give answer after test solutions given by us. Then, I solved this problem as follow. To save generated fpdf i have used this code..:

$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);

To read (retrieve from database) from my database was preferable to me use pdo code:

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
}

Those codes worked perfectly. I hope this contribution helps others to turn off headache with this problem. Best Regards.

长伴 2024-08-09 06:04:48

我遇到了与上面提到的同样的问题,更仔细地查看 phpmyadmin,我注意到 pdf 的插入是以十六进制完成的,而 fpdf 返回二进制,我的情况的解决方案是使用 bin2hex():

$_bin = $_pdf->Ouput("S");
$_hex = "0x" . bin2hex($_bin);

然后你可以插入sql查询中的这个$_hex不使用addslashes()或任何东西...(当然,我认为它必须插入到中型或长型blob中)

I encountered the same problem as mentioned above, looking more closely at phpmyadmin, I noticed that the insert of a pdf is done in hex, while fpdf returns binary, the solution in my case was to use bin2hex():

$_bin = $_pdf->Ouput("S");
$_hex = "0x" . bin2hex($_bin);

And you can then insert this $_hex in a sql query without using addslashes() or anything... (of course it has to be inserted in a medium or long blob i think)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文