How to avoid "header already sent" warning when loading a pdf In drupal 7, when I load a pdf page in a new tab, and after reloading the initial page, I have this warning:

Warning : Cannot modify header information - headers already sent in invoices_callback() (line 1093 in C:\xampp\htdocs\drupal\sites\all\modules\custom_profile\custom_profile.module).
Warning : Cannot modify header information - headers already sent in drupal_send_headers() (line 1221 in C:\xampp\htdocs\drupal\includes\bootstrap.inc).


Actually, I have a link in my initial page (named 'my-account/invoices') which redirects to a PDF page named 'my-account/invoices/%invoice_number'.
This last one is loaded by a 'page callback' function :

function invoices_callback($var){
require_once('sites/all/libraries/dompdf/dompdf_config.inc.php');

$filename = 'Invoice n°' . $var . '.pdf';
$dompdf = new DOMPDF();
    $dompdf-&gt;load_html('&lt;div&gt;Test n° : ' . $var . '&lt;/div&gt;');
    $dompdf-&gt;render();
    $dompdf-&gt;stream($filename, array('Attachment'=&gt;0));
    header('Content-type: application/pdf');

}


As you see, I didn't use a pdf module, like printer, which is too heavy. I use a custom module which implement a page callback function, and inside I use dompdf library.
The pdf is displayed normally, but when I come back to initial page I have these warnings.

I have tried several things:


I removed the header function. Effect: the first warning is gone but I still have the second. It seems like the stream method of DOMPDF class wants to sent a header...
I have added a charset utf-8 to the header function
I used ob_start() and ob_end_flush() functions at the beginning and at the end of the code. Surprisingly doesn't work.
I lastly use drupal_add_http_header function. Doesn't remove warnings.


What i can do is to call a script in an external link, because my test work when i call a php script located elsewhere. But for the UX, i try to have all my scripts managed by drupal, and i want the invoices to be called by a simple alias url (my-account/invoices/%invoice_number).

So my question is simple: How to avoid these warnings without moving my script to an external location?
So, this question is very specific. The problem of 'headers already sent' warning is common, and each situation is specific, but here...

I don't need to send header-content-pdf, it is redundant, because the stream method of dompdf object sent it. So I had to erase this line.

Secondly, the most important thing is that: My code is in a page callback function, which is executed by drupal at a moment of the page generation process. After a page callback function is executed, the http headers are not sent yet, it is the job of the delivery callback function which is by default drupal_deliver_html_page. We can override this default behavior by adding in the hook_menu item the delivery callback property:


  "delivery callback": The function to call to package the result of the page callback function and send it to the browser. Defaults to drupal_deliver_html_page() unless a value is inherited from a parent menu item. Note that this function is called even if the access checks fail, so any custom delivery callback function should take that into account. See drupal_deliver_html_page() for an example.


Implementing our custom delivery callback function should work... But I didn't try it... Because, in my research, i found this function: drupal_exit()


  Performs end-of-request tasks.
  In some cases page requests need to end without calling drupal_page_footer(). In these cases, call drupal_exit() instead. There should rarely be a reason to call exit instead of drupal_exit();


But here, for me there is a reason to end the request roughly: The stream method of the dompdf object render the page as i want, ie a pdf page. So to be clear, here is my new code:

function invoices_callback($var){
require_once('sites/all/libraries/dompdf/dompdf_config.inc.php');

$filename = 'Invoice n°' . $var . '.pdf';
$dompdf = new DOMPDF();
$dompdf-&gt;load_html('&lt;div&gt;Test n° : ' . $var . '&lt;/div&gt;');
$dompdf-&gt;render();
$dompdf-&gt;stream($filename, array('Attachment'=&gt;0));
drupal_exit();


}

The stream method sends the http header and renders the page, we don't need anything else, so we exit. It takes me a lot of time, i know how drupal generates a page now. Hope this helps.