我需要使用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
文件正确显示,所以我认为这是正确生成的,问题出在数据库中。
提前致谢。
答案 0 :(得分:3)
实际上出于安全原因:
addslashes()
,而是使用mysql_real_escape_string()
代替在这种特定情况下(因为它是二进制数据):
stripslashes()
addslashes()
替换为mysql_real_escape_string()
答案 1 :(得分:2)
你不应该剥去任何(背面)斜杠。添加它们时,它们在查询中用作转义字符,不会出现在字段中。
尝试更改此
$content = stripslashes($rs['myblobfield']);
进入这个:
$content = $rs['myblobfield'];
答案 2 :(得分: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;
答案 3 :(得分:1)
更换
header("Content-Length: ".strlen(content));
与
header("Content-Length: ".strlen($content));
为我工作。
答案 4 :(得分:0)
解决了!
我也遇到了同样的问题,正在尝试上面提到的想法。解决这个问题的是我的MySQL数据库将PDF存储为blob
而不是mediumblob
。一个blob字段限制为64K,因此截断了我的PDF的其余部分,其中包括有价值的数据,包括EOF(因此令人讨厌的Adobe错误)。
要确认,请下载其提供的PDF文件,然后查看文件大小。如果它正好是64K,您需要通过将字段设置为mediumblob
来在数据库中腾出更多空间。
感谢大家的帮助!
顺便说一下,我遵循了托托的建议并使用mysql_real_escape_string()
代替:
stripslashes()
addslashes()
替换为mysql_real_escape_string()
通过对原始海报代码的更改,它有效!
答案 5 :(得分: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
}
这些代码完美无缺。我希望这个贡献可以帮助其他人解决这个问题的头痛。最诚挚的问候。