Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TCPDF & mPDF error: Some data has already been output to browser, can't send PDF file

The Problem:

TCPDF & mPDF error: Some data has already been output to browser, can't send PDF file I gave up on trying to fix the error with TCPDF and installed mPDF only to get the same error when attempting to render the document to the browser. I can save the document just fine and have it displayed in the browser upon retrieval.

Additionally, this error only presented itself after switching from my dev server to my host server. Works fine on DEV server (DEV server = WAMPSERVER, PROD server = Hostgator Linux).

Troubleshooting:

I've read the many volumes of other discussions around the internet regarding this problem and I can find no white space related issue. I have condensed the request to the following:

<?php
ob_start(); 
$html = "Hello World";
include("../mpdf.php");
$mpdf=new mPDF(); 
$mpdf->WriteHTML($html);
$mpdf->Output();
ob_end_clean();
?>

Tried the same concept with TCPDF using ob_clean() method before writeHtml. Same error in all cases (I can assure everyone this is no white space related issue - I even viewed the file in hex to make sure there were no odd characters being inserted by the editor).

Possible Clue:

I was finally able to get a clue as to what's going on when I moved the entire mPDF library and classes and folders to the public_html folder, rather than from inside my application folder (a symfony project). Under this scenario, when I pointed my browser to the example pages, it rendered just fine with no errors at all (and it was super fast btw). So, I know it works, and I know there is no white-space related issue, or any other related issue, regarding the code or installation (on the mPDF/TCPDF side of things). Which leads me to believe either symfony is inserting headers of some sort (which I tried removing using: clearHttpHeaders() ), or there is a PHP INI or CONFIG setting I am missing somewhere on the PROD server.

Does anyone have ANY idea of what's going on here??

Update: stream dump:

Request URL:http://www.example.com/mpdf
Request Method:GET
Status Code:200 OK

Request Headers
GET /mpdf HTTP/1.1
Host: www.example.com
Connection: keep-alive
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,/;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Cookie: __utma=44708724.1463191694.1383759419.1383759419.1383765151.2; __utmz=44708724.1383759419.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none); PHPSESSID=9c7c802200b9d8eefe718447755add5f; __utma=1.813547483.1383767260.1385127878.1385130071.38; __utmb=1.7.10.1385130071; __utmc=1; __utmz=1.1383767260.1.1.utmcsr=(direct)|utmccn=(direct)|utmcmd=(none)

Response Headers
Cache-Control:no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Connection:Keep-Alive
Content-Type:text/html
Date:Fri, 22 Nov 2013 14:59:52 GMT
Expires:Thu, 19 Nov 1981 08:52:00 GMT
Keep-Alive:timeout=5, max=75
Pragma:no-cache
Server:Apache
Transfer-Encoding:chunked

Nothing is jumping out at me... any other thoughts?

like image 881
Patrick Avatar asked Nov 22 '13 14:11

Patrick


4 Answers

Most probably it's BOM marker, use your IDE to remove it, other hot fix can be:

<?php

$html = "Hello World";
include("../mpdf.php");

ob_clean(); // cleaning the buffer before Output()

$mpdf=new mPDF(); 
$mpdf->WriteHTML($html);
$mpdf->Output();

?>
like image 57
biesior Avatar answered Oct 20 '22 16:10

biesior


It could be some warning issued from PHP before the pdf->output. The warning text is sent to the client's browser and thus the file cannot be sent.
If your warning level is not the same for DEV and PROD, that could explain the difference of behavior.

In my case, with TCPDF, I had many warnings such as "date() it is not safe to rely on the system's timezone settings...", then the error "Some data has already been output to browser, can't send PDF".
Adding the function date_default_timezone_set() in my php source code solved the warnings and the error.

like image 23
tetorea Avatar answered Oct 20 '22 15:10

tetorea


I have got the same error.

Solve this using op_start(); and ob_end_clean();

PHP is an interpreted language thus each statement is executed one after another, therefore PHP tends to send HTML to browsers in chunks thus reducing performance. Using output buffering the generated HTML gets stored in a buffer or a string variable and is sent to the buffer to render after the execution of the last statement in the PHP script.

But Output Buffering is not enabled by default. In order to enable the Output Buffering one must use the ob_start() function before any echoing any HTML content in a script.

[reference credit][1]

[PHP | ob_start() Function][2]

public function gen_pdf($html, $user_id, $paper = 'A4') {
        ob_start();//Enables Output Buffering
        $mpdf = new mPDF('UTF-8', $paper, '', '', 15, 15, 30, 20, 15, 5);
        $mpdf->mirrorMargins = 1; // Use different Odd/Even headers and footers and mirror margins

        $header = '';
        $footer = '';
        
        $mpdf->SetHTMLHeader($header);
        $mpdf->SetHTMLFooter($footer);

        $mpdf->SetWatermarkText('Watermark', 0.1);
        $mpdf->showWatermarkText = true;
        $mpdf->WriteHTML($html);
        $fileName = date('Y_m_d_H_i_s');
        ob_end_clean();//End Output Buffering
        $mpdf->Output('Example_' . $fileName . '.pdf', 'I');
    }

So that it will clear all buffered output before processing mPDF.

Best Luck... [1]: https://www.geeksforgeeks.org/php-ob_start-function/ [2]: https://www.php.net/manual/en/function.ob-start.php

like image 26
Nurullah Avatar answered Oct 20 '22 14:10

Nurullah


I have the same issue, and add this line before $pdf->output():

error_reporting(E_ALL);

An then I found that I have BOM on some files. And I see a Warning message sent to the browser.

Best Luck !!

Regards

like image 40
Nicolas400 Avatar answered Oct 20 '22 16:10

Nicolas400