Reputation: 2229
I'm refactoring some old code and trying to understand headers
a bit better.
I read an awesome answer in the following post on No output before sending headers! Now I understand the 'why' but when it comes to implementation Its still a bit fuzzy.
My current page redirects back when the cancel button is clicked with the value searched.
I store the page the request was made from and the value in session variables allowing me to do this:
if (isset($_SESSION['searchPage'])){
header('Location:searchForm.php?ticket='.$_SESSION['product'].'&searchbtn=Search');
exit();
}
However to make this work in the display page I had to to use ob_start()
.
To avoid this workaround I found that I could redirect via javascript:
if (isset($_SESSION['searchPage'])){
echo '<script>window.location="searchForm.php?product='.$_SESSION['product'].'&searchbtn=Search";</script>';
exit();
}
Now to my questions
header()
. If a button click event causes redirection how do you handle redirection in php without using ob_start()
?Upvotes: 0
Views: 517
Reputation: 76413
edit
First and foremost, you might want to read up some more on redirecting using header
. Instead of just setting header('Location:...');
, redirect using the following code:
header ('HTTP/1.1 301 Moved Permanently');
header('Location:searchForm.php?ticket='.$_SESSION['product'].'&searchbtn=Search');
A 301 redirect is generally better for SEO, and most browsers will cache the redirect, so the client history stack will be more reliable, which is good news for the JS scripts that might use the history...
PHP. Relying solely on JS for redirecting the client is not a great idea. Clients might turn of your script, or if some error creeps in the JS code, the redirection won't work. Some borred teen might feel like messing with your code, and find possible security issues in your site.
2. How to use ob_*
, or how to use header
without ob_*
?
Just start your entry script (index.php
) with an ob_start()
call, to make sure. Perhaps use ob_implicit_flush(true)
, to implicitly flush your output buffer. But more importantly, just call ob_flush()
right after setting your headers.
Alternatively look into using a framework like Symfony2 and/or ZendFW. Code to handle redirects has been written for you many times, why not use it?
If you want to steer clear of output buffering, perhaps you might want to consider following certain patterns, or design principles (like MVC, IPO and the like) and write your code to (+-) always follow this order to take care of business:
Right after you've processed the request, you'll be able to redirect, and since you're not even close to rendering the output, let alone sending the headers, you're safe to redirect and or set the headers...
Update:
Just a link in response to your follow-up question Gruyere has a special secion on XSS attacks you might want to read... Though the main purpouse of the document is, I believe, how to safely use mashups (which are actually bonafide XSS injections). Anyway, they do a far better job at explaining why and how JS can be used to undermine security of any webapp.
Upvotes: 4
Reputation: 2735
I suggest a following approach:
function universal_redirect($url, $force_js = false) {
if (headers_sent() || $force_js) {
print('<script type="text/javascript">');
printf("location.href='%s';", $url);
print('</script>');
} else {
header('Location: ' . $url);
}
}
It is not always applicable but it is a good solution if you build admin-pages or when your project is big and complicated enough that you can't always guarantee that output was not yet started.
In general PHP redirect is much better for reasons given by @Elias Van Ootegem.
Upvotes: 0
Reputation: 39399
It’s always better to do it server-side. Both from an SEO point of view and because JavaScript redirects if a user has JavaScript disabled or there’s a problem downloading your JS file, or there’s an error in it that stops execution.
Upvotes: 1
Reputation: 4984
If you want just to send a user to another page on a button click, why not just to implement a link:
<a href="searchForm.php?ticket=<?=$product?>&searchbtn=Search">go back</a>
or button:
<button onclick="window.location='searchForm.php?ticket=<?=$product?>&searchbtn=Search'">go back</button>
Upvotes: 0
Reputation: 1
PHP redirection is best. Because even if a user has disable the script in his browser.
If you're using a noscript redirection then you can go for JS instead of PHP, so that in this case you can avoid ob_start().
Upvotes: 0