2012-01-30 142 views
1

我使用mPDF library直接从HTML输出生成PDF文档。问题是这个mPDF库是按原样编写的,它产生了数十个通告(未定义的索引,未定义的偏移量等)。我试图阻止输出它们,但没有任何帮助。无法摆脱mPDF中的PHP通知

我试图把error_reporting(E_ALL^E_NOTICE);以及error_reporting(E_ALL & ~E_NOTICE);,我插入到我的index.php,到类和方法,直接包括mpdf.php,也在mpdf.php的开始。我也试过与ini_set('display_errors', 0);的组合 - 所有这些指令都适用于整个web应用程序,但对于mpdf。因此,即使PDF格式正确且有效,我也无法输出(让用户下载它)。

此外,问题发生在我的HTML(简单的表,真的没什么特别的),而例子工作正常,没有通知。

所以我需要的帮助:或者摆脱通知或更好地帮助我找出为什么mPDF不适合我。

如果我用这个代码:

include_once(DIR_MPDF.'mpdf.php'); 
$mpdf = new mPDF(); 
$mpdf->useOnlyCoreFonts = true; 
$mpdf->SetDisplayMode('fullpage'); 
$mpdf->SetAutoFont(0); 
$mpdf->WriteHTML('<table><tr><td>HELLO WORLD</td></tr></table>'); 
$mpdf->Output(); 
exit; 

一切工作不错,但如果我尝试输出这个HTML:

$mpdf->WriteHTML('<table><tr><td>HELLO WORLD</td><td>HELLO WORLD</td></tr></table>'); 

我得到通知,因此PDF无法被输出。

如果我从MPDF将输出保存到文件中(使用例如file_put_contents())时,PDF是有效的,因此,即使我使用复杂HTML可读 - 但仍然是通告被印刷到浏览器。无论如何,我需要提供PDF下载,而不是保存到文件系统。

OK,我找到了一个解决方案,虽然它不是最好的做法(但它的工作原理):我附上代码ob_start();ob_end_clean();同时捕捉了$ PDF格式的字符串,我输出,而不是MPDF。

最终代码:

ob_start(); 
include(DIR_MPDF.'mpdf.php'); 
$html = $this->render(TRUE); 

$mpdf = new mPDF('utf-8','A4'); 

$mpdf->useOnlyCoreFonts = true; 
$mpdf->SetDisplayMode('fullpage'); 
$mpdf->SetAutoFont(0); 

$stylesheet = file_get_contents(DIR_APPLICATION.'view/stylesheet/declaration.css'); 
$mpdf->WriteHTML($stylesheet,1); 

$mpdf->WriteHTML($html); 

$pdf = $mpdf->Output('', 'S'); 
$ob = ob_get_contents(); 
ob_end_clean(); 

if (headers_sent()) 
    die('Some data has already been output to browser, can\'t send PDF file'); 
header('Content-Description: File Transfer'); 
header('Content-Transfer-Encoding: binary'); 
header('Cache-Control: public, must-revalidate, max-age=0'); 
header('Pragma: public'); 
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); 
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 
header('Content-Type: application/force-download'); 
header('Content-Type: application/octet-stream', false); 
header('Content-Type: application/download', false); 
header('Content-Type: application/pdf', false); 
if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) { 
    header('Content-Length: '.strlen($pdf)); 
} 
header('Content-disposition: attachment; filename="invoice.pdf"'); 
echo $pdf; 
exit; 
+1

可能mPDF在被调用时正在改变错误级别/报告吗?您可以尝试通过使用具有相关表达式的'@'运算符来抑制错误,但这不是一个好习惯。可能是库的更新或配置设置? (我不知道mPDF) – hakre 2012-01-30 17:22:10

+0

@hakre,没有这样的设置(AFAIK),但我会尝试@符号。 – shadyyx 2012-01-30 17:27:51

+0

@shaddyyx:确保由于您的输入而未给出警告。只是说,你的代码看起来很干净,可能HTML不可接受? – hakre 2012-01-30 17:30:31

回答

0

虽然没有答案,因为我还没有发现任何其他适当的解决方案,这里是我迄今(主要是从上面我的问题复制)摘要:

ob_start(); // <--| This is very important to start output buffering and to catch out any possible notices 
include(DIR_MPDF.'mpdf.php'); 
$html = $this->render(TRUE); 

$mpdf = new mPDF('utf-8','A4'); 

$mpdf->useOnlyCoreFonts = true; 
$mpdf->SetDisplayMode('fullpage'); 
$mpdf->SetAutoFont(0); 

$stylesheet = file_get_contents(DIR_APPLICATION.'view/stylesheet/declaration.css'); 
$mpdf->WriteHTML($stylesheet,1); // <--| By the second param we are saying to MPDF that it is icnluding only stylesheet 

$mpdf->WriteHTML($html); 

$pdf = $mpdf->Output('', 'S'); // <--| With the binary PDF data in $pdf we can do whatever we want - attach it to email, save to filesystem, push to browser's PDF plugin or offer it to user for download 
$ob = ob_get_contents(); // <--| Here we catch out previous output from buffer (and can log it, email it, or throw it away as I do :-)) 
ob_end_clean(); // <--| Finaly we clean output buffering and turn it off 

// The next headers() section is copied out form mPDF Output() method that offers a PDF file to download 
if (headers_sent()) 
    die('Some data has already been output to browser, can\'t send PDF file'); 
header('Content-Description: File Transfer'); 
header('Content-Transfer-Encoding: binary'); 
header('Cache-Control: public, must-revalidate, max-age=0'); 
header('Pragma: public'); 
header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); 
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); 
header('Content-Type: application/force-download'); 
header('Content-Type: application/octet-stream', false); 
header('Content-Type: application/download', false); 
header('Content-Type: application/pdf', false); 
if (!isset($_SERVER['HTTP_ACCEPT_ENCODING']) OR empty($_SERVER['HTTP_ACCEPT_ENCODING'])) { 
    header('Content-Length: '.strlen($pdf)); 
} 
header('Content-disposition: attachment; filename="invoice.pdf"'); 
echo $pdf; // <--| With the headers set PDF file is ready for download after we call echo 
exit; 

正如上面的注释中所写的那样,它就在我(或客户端:-))之后,将对从mPDF返回的PDF数据执行什么操作。我使用这个PDF通过应用程序在更多的地方生成,并且主要提供PDF下载,但我也将它附加到电子邮件(用户付款,我生成PDF发票并通过电子邮件发送)。

我发现没有解决方案(也没有更多时间这样做)来阻止mPDF生成通知,并且还没有失去理由来“修复”mpdf.php(使用其1.34 MB的PHP代码)因此这是(现在)唯一适用于我的解决方案。

也许它会帮助别人。

+0

@shadyx你有没有找到另一种解决方案 - 虽然我的PDF格式正确(但我收到了很多我想摆脱的通知),但我遇到了类似的问题。 – pepe 2012-08-05 02:51:52

+0

@torr对不起,我没有。只有使用输出缓冲功能,我才能摆脱PHP注意消息并正确输出PDF ...... – shadyyx 2012-08-06 10:01:45

+0

MPDF 6.x中的通知消失了吗? – 2015-08-26 13:28:33

0

看来只是当它试图写出每个页面的新表标题时发生错误。 我在V 5中注释掉了。4 线26210

#$this->TableHeaderFooter($tablefooter,$tablestartpage,$tablestartcolumn,'F',$level, $firstSpread, $finalSpread); // mPDF 5.3.36 

那里没有得到,无论绘制这样注释掉这行已经不是杀死通知书外没有其他效果的标题。

0

如果您在ob_end_clean()之后使用$mpdf->Output(),甚至可以在浏览器中不显示PDF!我在OpenCart中使用它。但是您需要使用ob_start()ob_end_clean()

+0

感谢您的回答,但您能否告诉您答案与接受答案不同?这是非常简短的没有任何代码的例子,它是在一年半后... – shadyyx 2014-08-04 07:49:45

+0

我找到了你的答案,但你使用$ pdf = $ mpdf->输出('','S');在ob_end_clean之前,我在电子邮件中使用这个pdf。但是,如果在ob_end_clean之后使用$ mpdf-> Output(),则通知也消失了,并且您可以在浏览器中显示PDF而不发出通知。这从你的答案中不是很清楚..你只在你的例子中写下关于下载.. – Francois99 2014-08-05 23:27:33