user3712617
user3712617

Reputation: 21

Getting 'Headers already sent' with TCPDF

EDIT 2: The problem is not solved; I found a work around by switching to an older version of the file, which was using ezpdf instead of TCPDF, and altering it to get the desired printout (I don't know why only one page in the entire website was changed to TCPDF, but apparently it happened). I would still like to know if there is a way to fix this problem, as the code for TCPDF functions correctly on the server running php 5.2, but not the new server. However, it no longer remains a major priority.

After submitting a request for a PDF, I get nothing; just a blank page. This is all code taken from another server (we are updating php versions to 5.3) and the code works fine on the first server.

Warning: Cannot modify header information - headers already sent (output started at filepath in path/tcpdf.php) TCPDF ERROR: Some data has already been output to browser, can't send PDF file

After some debugging, I noticed that the problem is a 'headers already sent error', which I've encountered several times while updating this site. Most of these errors are fixable using meta http-equiv, as they are mostly just page-refreshes. However, TCPDF uses headers to make the PDF file and force a download.

How can I get case 'D' to work, without needing headers, and if it can't be done, can case 'I' be altered to work without headers instead?

I have tried using ob_clean() before $pdf->output(). I have also tried removing require_once('./common/tcpdf/config/lang/eng.php'). Both of these have fixed problems for other people, and I have extensively researched the topic. I do not think it will work in this case, because I am aware that the website has already started output at this point.

What I want is an alternative to using headers (meta http-equiv?) in case 'D' (preferable) or case 'I' (doable) in the code below, that will give me the same results (a pdf download or a pdf opened in a new tab or window). Unless, of course, there is another fix. If not, I will have to re-write the page without using TCPDF.

EDIT: On the original server, 'generate pdf' causes the page to reload and then, after a long wait (while it queries the database), it forces a download on the user. On the new server, the page is reloaded, the long wait for the query occurs, and then the menu actually breaks (log out is removed and another button is moved beneath the rest of the menu bar) and nothing else happens.

Code taken from tcpdf.php:

case 'I': {
                // Send PDF to the standard output
                echo "<script>console.log('some log');</script>";
                if (ob_get_contents()) {
                    $this->Error('Some data has already been output, can\'t send PDF file');
                }
                if (php_sapi_name() != 'cli') {
                    //We send to a browser
                    header('Content-Type: application/pdf');
                    if (headers_sent()) {
                        $this->Error('Some data has already been output to browser, can\'t send PDF file');
                    }
                    header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
                    header('Pragma: public');
                    header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
                    header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');  
                    header('Content-Length: '.$this->bufferlen);
                    header('Content-Disposition: inline; filename="'.basename($name).'";');
                }
                echo $this->getBuffer();
                break;
            }
                case 'D': {
                    // Download PDF as file
                    if (ob_get_contents()) {
                        $this->Error('Some data has already been output, can\'t send PDF file');
                    }
                    header('Content-Description: File Transfer');
                    if (headers_sent()) {

                        $this->Error('Some data has already been output to browser, can\'t send PDF file');
                    }
                    header('Cache-Control: public, must-revalidate, max-age=0'); // HTTP/1.1
                    header('Pragma: public');
                    header('Expires: Sat, 26 Jul 1997 05:00:00 GMT'); // Date in the past
                    header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
                    // force download dialog
                    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);
                    // use the Content-Disposition header to supply a recommended filename
                    header('Content-Disposition: attachment; filename="'.basename($name).'";');
                    header('Content-Transfer-Encoding: binary');
                    header('Content-Length: '.$this->bufferlen);
                    echo $this->getBuffer();
                    break;
                }

Upvotes: 2

Views: 7277

Answers (5)

user3529631
user3529631

Reputation: 1

This worked! Edit "tcpdf_static.php" go to the file called "tcpdf_static.php" from the tcpdf vendor folder, and in the function sendOutputData, replace echo $data with the following lines to resolve the issue. I found that it was necessary to clean the buffer first (there might be more than one open). This was on TCPDF version 6.7.7

while (ob_get_level()) {
        ob_end_clean();
    }

    ob_start();
    echo $data;
    ob_end_flush();
    die;

Upvotes: 0

Aditya
Aditya

Reputation: 151

To resolve this error, go to the file called as "tcpdf_static.php" from the tcpdf vendor folder, and in function sendOutputData, replace echo $data with following lines to resolve the issue

ob_start();        
ob_end_clean();// All other content        
echo $data;
ob_end_flush();
die;

Hope it helps

Upvotes: 0

RationalRabbit
RationalRabbit

Reputation: 1067

I have seen a lot of references around the Web to use ob_start(), with ob_end_flush() at the end of file. Maybe that works in some situations, although I really don't understood how it would. Not disagreeing - just saying I don't understand, and I did not find it as a solution to the problem.

However, I have found that using ob_start() at the top of the file and ob_end_clean() BEFORE the output should do the trick.

<?PHP
    ob_start();
    // All other content
    ob_end_clean();
    $pdf->Output('MyPDF_File.pdf', 'D');
?>  

Upvotes: 4

Hasan
Hasan

Reputation: 29

add

code ob_start() 

in early function and ob_end_flush(); after $pdf->output()

Upvotes: 2

Navelpluisje
Navelpluisje

Reputation: 286

There's an echo before setting the header. Just remove:

echo "<script>console.log('some log');</script>";

There may not be eny echo or print before ending the header

Upvotes: 1

Related Questions