What is the correct order to use the PHP header and ob_start functions?

Asked

Viewed 1,233 times

6

Before starting the ob_start function();

header('Content-Type: text/html; charset=utf-8');
ob_start();
....
ob_end_flush();

After starting the ob_start function();

ob_start();
header('Content-Type: text/html; charset=utf-8');
....
ob_end_flush();

What should be the right way to send HTTP headers in a PHP script?

  • 3

    Just to explain the reason for the closing vote, the question is without a defined focus because it is not wrong to use before or after a header(). This will depend on the context, the reason why you need to invoke output buffering functions. If you add to which context it applies, it can be a valid question. But the way it is, you can see for yourself in the answers you received... None of them are wrong, but they are addressing distinct or null contexts.

4 answers

10


The answer is: It makes no difference, depending on where you call the ob_start.

What I answered is controversial, but you need to understand how buffer capture works and how it works to send wiring to the customer in order to understand.

So read it patiently:

Why doesn’t it matter if I call ob_start before header in the specified case?

When you call ob_start, is telling PHP to store in memory everything that is being sent to the client. That is, instead of its echo print something to the browser immediately, that output sequence is saved in memory.

Look at this little example.

Don’t get it yet?

If you still don’t understand, you may be confused about using the ob_start with the recommendation to call the header and session_start in the correct order. The correct order is: headers functions must be called first that output to the customer.

Customer output is when you issue a echo or anything else that sends information to the browser.

But why is there such a recommendation to call functions from headers before sending an output to the customer?

Just so you understand, these two functions send the browser a header. The header, as its name indicates, should be sent before the content.

An HTTP response is formatted something like this:

HTTP/1.1
Content-Type: text/plain;charset=utf-8

Hello World!

That is, first comes the header, then the content. The part above is the header and, after the line break, comes the content (what you usually send through the echo).

So that’s why it’s important you call the functions header and session_start, so that headers are sent to the customer correctly.

Example:

 header('content-type: text/plain;');

 echo "Olá, mundo";

Otherwise, if you do otherwise, you may generate the famous error described in this question:

Error - Cannot Modify header information

That’s the kind of mistake Warning, PHP emits when the programmer calls the function header after PHP sent the Client content.

But then why did you say to call ob_start before header makes no difference?

Because with ob_start, as said earlier, the output that would normally go into the browser is saved all in memory, until you call a function ob_get_contents (or similar) that captures the output that was sent to memory, or until the script is finished (when the script is terminated, the buffer capture is automatically released by php).

So with the ob_start, you could do that, which would be totally acceptable:

  ob_start();

  echo "Olá, mundo";

  header('content-type: text/plain');

  echo ob_get_contents();

The code above would not give error because I called ob_start before the echo, causing this chunk to be captured into the memory instead of going directly to the customer. Then, when I called ob_get_contents, the output that was in the memory came out to the customer.

This happened because the ob_start stores the data sent between the place where it was called up to the call of a capture function or until the end of the script execution.

See a similar example here.

If you did it the way below, it would generate an error:

   echo "olá mundo";

   header('content-type: text/plain');

See the error here.

Note that in the first example, no Warning, because of the ob_start().

That is, in your case (which is similar to the examples I posted), when using ob_start, the order makes no difference, since the output buffer does not let the outputs be issued immediately, but later the call of some function that recovers the buffer or at the end of the script execution.

My recommendation

Although the ob_start do not let the error occur when a data output function is called first than the header sending function, my recommendation is that you always call the headers functions as soon as possible for didactic reasons (Every programmer will wait for the call from headers to come first that sending the content to the customer).

In case you give up using ob_start someday, you would have no problem removing it, as the headers would be being called before even!

So to sum up: If ob_start is called before any data output, when calling header after a echo, it won’t make a difference.

Note: Note that the ob_start captures the output from the moment it is called. If you call it after sending a content to the client, the output will not be captured.

Example

Note²: The ob_start makes the output to the client can be used at a later time than the header functions call. If you call ob_start and send the output before the header, will also receive a Warning.

  • Who gave the negative could prove my answer wrong, please?

  • I don’t know if it was, but just stating that a retaliatory vote is not a real reason to vote negative.

  • They gave negative in mine too, someone is negatively in the answer Zuera. Direct is happening this. And I really liked your explanation, I had no idea you had so much.

4

The interesting use of ob_start is to store the information that would be sent to the browser in a temporary memory cache.

There is no official recommendation on the subject, but I point out that you always call the ob_start function first.

Imagine you have the following code:

header('Content-Type: text/html; charset=utf-8');
ob_start();
try {
  algumaFuncaoQueGerouException();
} catch(\Exception $ex) {
  ob_end_clean();
  echo trataErroComoJSON($ex);
}

In this case you can capture all the content that would come out to the browser and ignore it by displaying only the error message in a JSON format. But what about the header that’s already been sent?

The header will have already been sent, and you will have to live with it, even if it is incorrect. On the other hand, if you captured the header with the ob_start, you can ignore it as well and avoid creating confusion for the browser. Of course you can overwrite all the headers again, but this will become much more laborious than simply ignoring them.

4

You should always put the header first, because if you have a redirect, you may end up affecting where your users will be redirected.

Another thing that happens is that information can get stuck in the buffer until you release it. I’ll give you a practical example.

ob_start();
header("location: 1.html"); 
echo "send data"; 
header("location: 2.html"); // substitui o 1.html
ob_end_flush(); //e apenas aqui será enviado.

As you can see in the code above, ob_start() will store the header until it is released through ob_end_flush()

More information

3

The PHP documentation does not talk about or recommend anything about it.

It is known that headers are sent when the first byte is sent to the browser, so for the sake of good practice, I recommend setting the headers first before using ob_start()

  • 1

    Doesn’t make sense that you said, since the ob_start starts the output capture. So, regardless of the order, the output the user sent with a echo or with anything else would only be processed after the execution of the script, or with the call of ob_get_contents (and similar functions that recover what was captured in the buffer). It even has a gambiarra that the person does with ob_start precisely for not knowing where started the data output to the browser.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.