PHP redirect without header() or meta - php

I'm trying to design a page which does some database actions, then redirects to user back to the page they came from. The problem is that I use a require() function to get the connection to the database, so the headers are already sent. A meta tag is out of the question since I want it to look like all the processes are done from the page they came from. Any tips? Is there a way I can use the require() and the header() or do I have to drop one? Is there an alternative to header()?

If you can't send the header() before some content gets sent, use output buffering by placing an ob_start(); at the beginning of your script before anything is sent. That way, any content will be stored in a buffer and won't be sent until the end of the script or when you manually send the buffer's contents.
On another note, simply requireing another file would not generate any headers/content unless that included script sends them. The most common "hidden" cause of this is unnoticed whitespace before or after the <?php ?> tags.

As Artefacto noted, connecting to the database should not require any output. Fix whatever you're including (e.g. database_connect.php) not to output. See this search on the "headers already sent" issue, which may help you find "hidden" output.

ob_start(); // start output buffering
echo "<html......"; // You can even output some content, it will still work.
.
.
.
.
.
header("Location: mypage.php");
ob_flush(); //flush the buffer
In this case, all output is buffered. This means, the headers are processed first, then the output comes to play...

You cannot send any headers after some content has already been sent. Move the header() call to be before the require() call.

You cannot send headers after any data has been sent to the client.
However, using require does not meen that you output something. If i understand your right, you can include your database files, run your queries and then redirect the user. This is perfectly valid.
If you need to send some output (why if you need to do a redirect?) another option is to use output buffering. By using output buffering, you're not sending the data to the browser when you echo it, but you store it in a buffer. The data will be sent when you call ob_end_flush or you reach the end of the script. After ob_end_flush, you won't be able to send any new headers. You start output buffering with ob_start.

It is possible to use header() with require() when I use output buffering. That means that the whole script is buffered and first send when the script has come to an end.
I have done it by doing this
ob_start("ob_gzhandler"); //begin buffering the output
require_once('/classes/mysql.php');
// Some code where I access the database.
header('/somepage.php');
exit;
ob_flush(); //output the data in the buffer

Related

ob_start() and ob_implicit_flush(true) using at the same time cause an issue

I need to echo some output while executing php file ,beacuse execution takes 10 sec and end of 10sec page should be directed via header("Location:test.php)
However If I use ob_start and ob_implicit_flush(true) at the same time , we cannot direct page and getting
Warning: Cannot modify header information - headers already sent by
I also need to use ob_implicit_flush(true) to print output while execution.
How can I display output and direct page ?
You cannot output both body content and a redirect header in the same response, much less output the body before the header. The HTTP headers come first, so you cannot output a body before headers and you cannot output headers after the body has been output. Further, a redirect header causes the request to be immediately redirected before the browser will display any of its content, so the entire thing doesn't work on two levels.
If you want to display anything while the server is doing something, you'll need to use Javascript in some form or another.
If you use header() function there MUST be no output BEFORE it. But of course it can be after using the function.
ob_start starts the buffer to work while ob_implicit_flush tells to use no buffer at all. So the two functions cannot be combined that way.
Example:
ob_start(); //set buffer on
print('Hello World'); //no output since buffer on
ob_implicit_flush(true); //buffer switched off again
print('Test'); //prints 'Hello World' and 'Test'
header('Location: ...'); //ERROR: output already done
You have now to decide if you want to output information from your script OR make the redirection.
Output something AFTER header is possible but it makes no sense as you will not see it anymore.
Maybe you can use the ob_get_length() function to check if there was some output and then decide if you switch page or output the buffer:
ob_start(); //set buffer on
print('Hello World'); //no output since buffer on
if(ob_get_length() > 0)
ob_end_flush();
else
header('Location: ...'); //will not be executed if output was generated

Check if part of output has already been sent in PHP

In PHP, is there a (ready-made) way to check if a part of the output has already been sent to the client?
I know that with headers_sent() you can check if the headers have already been sent, but I also want to check if any output has been sent (so that e.g. the HTTP header Content-Length > 0).
(Notice that ob_start() starts output buffering from the moment when it is called. But third-party systems implementing my code might already have sent output, thus output buffering is unusable as far as I know.)
You could wrap your own ob_start around everything else and flush it when you decide to. It works even if other ob_start's and flushes are inside. Take this example :
ob_start();
[...]
//some 3rd party app which is included on the way
[...]
ob_start();
[...]
ob_flush(); //at this moment the buffer isn't flushed to the client
//but to the parent ob_start, which is yours, so no output
//is sent yet
[...]
//ok, we're done, we can output now
ob_flush();
PHP in most cases sends headers to Apache only with some content or on the end of script execution. So, if headers are sent, some content is sent too. Furthemore, as I understand, Content-Length is calculated anyway after the script execution.

alternate php redirection method that works with output preceding it

so apparently if you do this:
<?php
echo 'something';
header("Location: http://something/");
?>
it will not work because there is an output preceding the header...
is there any other alternative php redirection method that works straight from php without installing anything and in which it will still work even if there's an output preceding it so that I don't have to worry about making sure that there is no output before, etc...
not, unless you do something in javascript or html tags in the page that you output itself
if preceding output is a problem
you can also use output buffering, see ob_start, ob_get
to get around that
There is no other way to do a php redirect, but you can fool it to still work even with code prior. You would buffer the content and only output it if there is no redirect or reaches the end of the script. Note: this may be resource heavy in some cases.
ob_start()
....CONTENT...
ob_end_flush();
There are no ways in PHP except using header()... before output is sent (headers be already sent)...
You can either use meta refresh in HTML that is set at zero seconds, or javascript.
But I wouldn't recommend javascript as some will have it disabled.
You could use a meta refresh tag.
You understand why this is impossible, right?
As soon as you echo "something" you have sent content to the client, and as part of that client headers were already sent. You can't retroactively modify headers you already sent, and you can't make two responses to one HTTP request.
ob_start() and ob_end_flush() will buffer the output instead of sending it to the client, which will allow you to get around this problem, BUT
a better solution would be to:
separate your logic code from your template so that you don't write anything to the screen until you already know you aren't going to redirect.

why do I need to end my ob_start()?

The php documentation suggests that I should end each ob_start() with an ob_end_flush(). I am using one on each page of a site, just to allow me to use firephp log methods anywhere in the app.
the app works fine, but I wonder if there is anything I don't know that might be detrimental.
I think the reason for this suggestion is, that PHP flushes your output buffer implicitly when not using one of the ob_end_* functions. While not an error, this can cause problems when not expecting it. The PHP-docs try to protect you from these kind of problems. If you are aware of the implicit flush, it is probably not an issue.
You can use Output Buffering as
<?php
ob_start();
echo "Some text you want to echo on page!!";
header("Location:somepage.php");
ob_end_flush();
?>
The problem is that we cannot send the header after we start sending the output. To solve this we buffer the output. The function ob_start turns output buffering on. While output buffering is active no output is sent from the script (other than headers), instead the output is stored in an internal buffer. So the echo output will be buffered. Next we send the header without any problem as we've not yet spit out any output. Finally we call ob_end_flush to flush the internal buffer contents and to stop output buffering.
if there is loops, for example, some one can start buffering. And calls your function. When he tries to ob_end_flush code gathers your contents.

How to set cookies via PHP in the middle of a document?

how can I set cookies in the middle of a document, without incurring a 'headers already sent' error? What I'm trying to do is make a log out script (the log in cookie setting works...so odd. Is it because it's enclosed in an if statement?) however I've already echoed the page title and some other stuff at the top of the page, before I've made this logout happen.
Thanks!
The easiest way is to use output buffering to stop PHP from sending data to the client until you're ready
<?php
ob_start();
// your code
ob_end_flush();
?>
Output buffering stores all outputted data until the buffer is flushed, and then sends it all at once, so any echos after the start will remain buffered until the end_flush and then sent
Try to decompose your application in two parts :
First, you unset the cookie, then you redirect user on the result page. It's a common way to work.
Also try to use a framework in your development, it will improve your skills and the maintenability of your code.
Cookies are sent in the headers, which are sent before anything else is sent. Therefore, if you have actually 'echoed' something to the client (browser), your headers have also been sent.
That said, you can buffer your output and send it all once all the code has been run (ob_start() and ob_end_flush())

Categories