2012-01-30 49 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