views:

66

answers:

2

I have a function which needs to redirect the page if a variable is set etc...

The problem is, this function is at the bottom of the php page.

This means, I have outputted alot of information, so I get a headers warning.

"Warning - Headers already sent by ..."

Is there any way to redirect after headers are sent?

Thanks

+10  A: 

What you should do is put ob_start() at the very beginning of your page, and ob_flush() at the very end. This way you don't run into headers already sent errors.

See those functions for further reference.

Damien
`ob_flush()` at the end is implicit and can be omitted. The benefit of this is that you won't accidentally come back to this problem months down the line if you add output content after `ob_flush()` somewhere in your application's control flow where that function call isn't visible.
eyelidlessness
This is IMO the cleanest solution; note that this works by buffering the headers and content and only sending them all together at the end of the page.
Piskvor
also not that depending on the size of your outpout and the number of visits this exact page has, it really could slow down your page due to storing all the strings into memory.
ITroubs
It also makes progressive rendering impossible. But so does gzip, which we're all using, right? Right? Bueller?
eyelidlessness
@eyelidlessness: you could try flushing the buffer here and there. Like after the HTML head for example. Most browsers won't render anything if the amount of data isn't enough though, so ... yeah. :)
DanMan
@DanMan, I'm pretty sure progressive rendering is impossible regardless of how many times you flush the buffer *if* you're using gzip (via `ob_gzhandler` or through Apache or whatever). And I think the benefits of gzip generally outweigh the benefits of progressive rendering. This can be alleviated somewhat with chunked responses, but the architecture needs to be pretty low-level in an application, ruling out many frameworks and off-the-shelf applications, even those targeted explicitly at developers, unless they're already built to handle it.
eyelidlessness
flushing by the way is pretty much useless on IIS because IIS has it's own output cache and send's the output as soon as it thinks it has enough to send, unlike apache, what does what you tell it to.
ITroubs
@ITroubs, Apache will limit flushes too. It might just be more lenient.
eyelidlessness
+2  A: 

There are ways, but they're basically workarounds:

The simplest one is the meta http-equiv:

<meta http-equiv="Refresh" content="0;http://www.example.com/newlocation"&gt;
  • some browsers will not like this when it's outside of the <head> element, and drop into quirks mode

Or, you can try the JavaScript redirect:

<script>
    window.location = 'http://www.example.com/newlocation';
</script>
  • which obviously won't work without JavaScript.
Piskvor
`http-equiv` headers have to be within the first few hundred bytes of the document or the browser will not treat them as HTTP headers.
eyelidlessness
@eyelidlessness: Interesting, I didn't know that. [citation-needed]?
Piskvor
@Piskvor, it might just be a legacy thing. I'm having trouble digging stuff up. But I do remember back in the day Microsoft documentation specifically warning developers to place HTTP-equivalent meta tags in the first N bytes or they won't be treated as headers.
eyelidlessness
i'd go with the jscript redirect or even better would be a clean refactoring so that the output is made after all the business logic processed every data and all the decisions are made so that before any output you can do your redirection OR if you need to do some output due to long processiong of data, one could refactor it in that way that eny required calculation is ready before any output is done.
ITroubs
@eyelidlessness well if Microsoft said so it might be only for IE and if they said it a long time ago it still should be relevant because changings towards W3C standards are somehow going pretty slow at IE development team ><
ITroubs
@ITroubs, yes, it may have been IE-only. But I should clarify that I only *think* I remember it being a MS source, it very well could have been A List Apart or any other popular web design/dev sources from the time. I just remember it's been some time. As for relevance, I'm loathe to trust, at the very least, IE 6-8 to get corner cases right in the first place, and the benefit of moving your HTTP-equivalent meta tags up is good anyway (it improves responsiveness if nothing else), if you can't control the actual web server's HTTP header output.
eyelidlessness
@ITroubs, regarding redirects, Javascript is probably the least reliable solution. Why would you go with that, excepting a refactoring?
eyelidlessness
Well in the OP's case it could be the only, not most reliable, but the only way because as you said, putting a http-equiv at the end of a document might have no effect. And if he can't do a reasonable refactoring to send the header before sending any output, i don't see a way to do it better than with the jscript. Please correct me if a am mistaken. I realy am willing to learn new things.
ITroubs
@ITroubs, I voted for output buffering. I think it's a more reliable solution. Edit: output buffering can be implemented by adding a single line of code to the top of the application. I think if the OP can't do that, they have bigger problems to solve with their team.
eyelidlessness