Redirections in PHP - php

If I want to redirect a user in PHP, all I've ever known to do was use the header('Location:' http://www.example.com) but I've been reading that this isn't the best way to redirect a user from page to page internally. What are some other options you can redirect a user?
Example: at the bottom it says:
Something Important to Remember
...I don’t recommend, for example, using header() to bounce your users around to different pages; there are better methods that reduce the number of page loads and give the user a more fluid experience...
http://tinsology.net/2009/06/creating-a-secure-login-system-the-right-way/

The snippet you provided is referring to issues where page1.php might execute some code followed by header('Lodation: http://www.example.com/page2.php'); and where page2.php then executes some code followed by header('Location: http://www.example.com/page3.php'); etc. This is very bad for user experience, and not very good for managing code either.
In cases where you genuinely need to redirect a user (301 redirect is probably the most common), using header is perfectly acceptable.

It isn't bad. However you could add 301 response code to make it more better, it is also better for Google to determine he should not visit that "old" site anymore.
<?php
Header( "HTTP/1.1 301 Moved Permanently" );
Header( "Location: http://www.new-url.com" );
?>

This is the accepted method for PHP-based redirection. If you can accomplish the redirect prior to PHP script execution, then you should - through .htaccess or server-level aliasing.
Check out the manual on header: http://php.net/manual/en/function.header.php

It's always sensible to avoid using header() internally because sometimes headers are already called. JavaScript redirects are absolutely fine and are used systematically in a lot of web applications. Browsers and search engines don't discriminate against or dislike JavaScript redirects. A simple example:
<?php echo '<script type="text/javascript">window.location.href="index.php"</script>'; ?>
Or using a variable:
<?php echo '<script type="text/javascript">window.location.href="' . $page . '"</script>'; ?>

Just use
header("Location: http://www.example.com");

Related

PHP: Best redirect technique

I'm currently using the excellent mobile detection script from: detectmobilebrowsers.mobi
This works really well however, it redirects every and any page on your main site (including any query parameters) to your mobile site's home page.
What I need is:
http://www.mydomain.com/page.php?var1=X&var2=Y
to direct to:
http://mobile.mydomain.com/page.php?var1=X&var2=Y
I have multiple pages that should redirect with the query string to their mobile versions.
What's the best way to approach this? I thought that I should:
Examine the $_SERVER['HTTP_REFERER'] for the page and query string, use a switch/case to loop through the 10 or so pages that I need matching on the main and mobile sites then change the referer URL in the mobile detection script.
Does this make sense?
I've been struggling to get the page and query... any advise and thoughts welcome.
if ($mobile_is_detected) {
header('Location: http://mobile.mydomain.com' . $_SERVER['REQUEST_URI']);
exit;
}
In addition to Andy's answer, when redirecting you should set the response status to 301.
Be careful, you may not call header() if you have printed any HTML or echoed anything before calling the function.
if ($mobile_is_detected) {
header('HTTP/1.1 301 Moved Permanently');
header('Location: http://mobile.mydomain.com' . $_SERVER['REQUEST_URI']);
}
You can use $_SERVER['QUERY_STRING'] to redirect to add the query string to the redirect URL in the first place.

more than one header in chrome not working - php

Im using PHP to track the clicks of all mailto links by rewriting the mailto: to my script and then setting the header of the referring page.
Initially I just had:
header("location: mailto:email#address.com");
...but this has an undesirable effect in IE8: it opens 2 email windows. So, in my attempt to resolve that issue I am now using:
header("Status: 200");
header("location: http://mypage.com");
header("Refresh: 0; url=mailto:email#address.com");
This works fine in IE but not chrome. I threw the "status" in there hoping to solve the mystery.
Other than detecting the browser and issuing different commands, what else could one do?
A location header should be accompanied by a 30X status code (like 302), not 200.
Check this out > http://php.net/manual/en/function.header.php
Especially those two parts:
The second special case is the
"Location:" header. Not only does it
send this header back to the browser,
but it also returns a REDIRECT (302)
status code to the browser unless the
201 or a 3xx status code has already
been set.
<?php
header("Location: http://www.example.com/"); /* Redirect browser */
/* Make sure that code below does not get executed when we redirect. */
exit;
?>
You send 200 and 302 at same time, and also you didn't follow the exit; rule.
You can play with my suggestions (especially the exit; part).
!!! Note !!! There was a bug in the past that makes the Chrome not to work if header("Status: 200"); wasn't set first, but not sure if it's fixed yet.
it would probably be better to use some AJAX to handle your problem here, and if your going to use AJAX use JQuery its just easier
firstly though mailto is not a preferred method on the web any more its too clunky and relies upon the default email client of the user being set up which in most cases you cannot rely upon.
So to address that have a link that is styled to look like your button.
once you have this use JQuery to send an ajax request to a PHP script that performs the counting and then if you wish upon receipt handle the success with a redirect (I only include that because I am unsure what your redirect achieves).
Its clean quick and the user will not notice a difference apart from your site will probably experience a speed increase :) hope this helps
Header location redirects the browser, so the other headers are ignored. You should send this header always as the last one. Also it's not good idea to execute any PHP code after you send the redirect.
You probably want to do this:
On first page:
header("Status: 200");
header("location: http://mypage.com");
exit();
On the http://mypage.com:
header("Refresh: 0; url=mailto:email#address.com");
The weird thing about chrome: it accepts the following header refresh.
<meta http-equiv="refresh" content="4; url=page.php" />
<button value="go further">
I place a button below this refresh for the browsers who does not support any type of header refresh.

$_SERVER['HTTP_REFERER'] is always empty - PHP

<?php
$camefrom =$_SERVER['HTTP_REFERER'];
if ((substr($camefrom,0,26) == "http://www.fromperson.com")
header( 'Location: http://toperson.com' ) ;
?>
I need to redirect to www.to.com if the request was made from www.from.com. This code resides in www.thridperson.com/index.php
$camefrom is always empty.
I have read that $_SERVER['HTTP_REFERER'] is not reliable. Is there any other way to perform this redirection?
Note: I have lost the access to old domain i.e fromperson.com. So, I cannot change this redirection logic it has to be done this way and it has to done only in thirdperson.com/index/php
$_SERVER['HTTP_REFERER'] is indeed unreliable. A client (browser) is not required to include it in the request. If you need a bullet-proof solution that will always work you will have to moddiffy your application on `fromperson.com' to include some GET parameter when linking to your web page, and then you can check if that GET parameter exists and then do the redirect.
No way to do according to my requirement

PHP Redirect after execution of code

I have a php page that takes in a bunch of url parameters and sends out an email. I am trying to have this page call another web page using the same url parameters, after the mail is sent. If I do the following, will my email be sent reliably? Is a redirect what I really want to do?
Update: Thanks for the tips. As you can see by my use of the +, I don't know any php. After reading all the answers so far I have come up with this:
Random code to send email...
file_get_contents('http://www.othersite.com/' . $_SERVER["REQUEST_URI"]. "?". $_SERVER["QUERY_STRING"]);
I believe this should initiate a GET on the other site with all the current parameters, which is exactly what I want. This way I don't have to deal with redirects. Any problems to this solution?
Update 2: Since my url was https, file_get_contents caused me some problems. There are ways to get around this but I just used header for a redirect and all worked well. Thanks everyone!
The question raised in the other answers whether your basic approach is really what you want is valid - check that first. Anyway, if it really is what you want to do (Is your target URL really identical to the one you're on?) you can indeed use
header('Location: http://www.othersite.com/' . $_SERVER["REQUEST_URI"]);
Just note the use of . to concatenate the string instead of +, you can't do that in PHP.
To do it really properly, you could use http_build_url to build a full valid URL from the current GET array. Code from the manual, modified a bit:
<?php
echo http_build_url("http://user#www.example.com/pub/index.php",
$_GET,
HTTP_URL_STRIP_AUTH | HTTP_URL_JOIN_PATH | HTTP_URL_JOIN_QUERY
);
?>
The header location call will be only called after the mail code so it won't affect your email.
Don't forget to call exit() after your header location call.
Also the string concat operator is not + it's . (dot).
if its the same application, why dont you call the same functions ?
if you want you could do file_get_contents .. instead of a redirect for the same effect.
If you just want to hit that page why not use file_get_contents
$data = file_get_contents('http://www.othersite.com/' . $_SERVER["REQUEST_URI"]);
echo $data;
The benefit with this is you don't have to physically go to the other site if you don't want to, equally if you control the script on the other site you could return a true or false in the HTML which could be checked upon return.
For full compliance (sometimes Chrome will not work with just a Location: header)
header( "HTTP/1.0 302 Found" );
header( "Status: 302" ); # this is for chrome compliance
header( "Location: http://www.othersite.com/' . $_SERVER["REQUEST_URI"] );
Another option is to echo the HTML tag:
<meta http-equiv="Refresh" content="1;url=http://www.othersite.com/<?php echo $_SERVER['REQUEST_URI']; ?>">
This allows you to set a delay time for redirecting (usually 1s), which is good in some situations so that the user doesn't become confused by a flash of content. You can put a 'Stand by while we redirect you' message or similar.

Javascript redirect vs PHP redirect, which would search engines see as regular content

I'm guessing that using PHP's header("location: here.html") would be much better javascript's window.location("here.html") as far as search engine visibility goes. I would assume that the server redirect would show google the correct content and the javascript redirect would be read as a page with the javascript redirect code in it.
Reason being is I have a client that wants me to take their current website and import it into a CMS system (I'm using e107) and I don't want their old pages to lose their current page rank. I was thinking of putting redirects on the old pages to the new pages in the CMS system.
The only way to forward on search engine rank is with an HTTP 301 (permanent) redirect.
Using PHP's header('Location') will give a 302 unless you specify the code like this:
header('Location: http://....', true, 301);
It might be easier to use .htaccess, like this:
RewriteRule ^old.php /new.php [R=301]
Yes, you want to do server side redirection (PHP) if you can.
<?
Header( "HTTP/1.1 301 Moved Permanently" );
Header( "Location: http://www.new-url.com" );
?>
via
You can also do this using
header("location: http://www.new-url.com")
but it won't be as good SEO wise

Categories