Setting a variable and using header() - php

I'm developing a custom content management script, and I'm working on page redirection.
The code below compares the URL code to the URL for the a certain page ID in the database, and if the two URLs are not the same, the user is redirected.
However, I want to add a variable, so that we can check if the page has been redirected or not. It isn't working.
if (isset ( $_GET ['id'] ) && $rawdata) {
if ($_SERVER ["REQUEST_URI"] != $rawdata ['htmltitle']) {
header ( "HTTP/1.1 301 Moved Permanently" );
header ( "Location: http://${_SERVER['SERVER_NAME']}:${_SERVER["SERVER_PORT"]}${rawdata['htmltitle']}" );
$redirected = true;
;
}
}
if ($redirected == true) {
print_redirect_nonexpected ();
}
function print_redirect_nonexpected (){
echo "<!-- REDIRECTED _ NOT _ EXPECTED ? -->";
}
The function isn't being run, so no echoing.
Any ideas what I'm doing wrong here?

Use this:
header ( "Location: http://".$_SERVER['SERVER_NAME'].$_SERVER['SERVER_PORT'].$rawdata['htmltitle']);
If $rawdata['htmltitle'] is full URL of your page, use this:
header ( "Location: http://".$rawdata['htmltitle']);
And also adding die() after header() is good.

When you send a Location: header, the user-agent stops loading the current page and loads whatever page you tell it to load, so you'll never see the output.
However, your code may* continue to execute in the background, so usually you want to follow your header() with an exit; to prevent unwanted behavior.
* Depends on server configuration and on ignore_user_abort.
Also, header("Location: /{$rawdata['htmltitle']}"); will suffice. Since you are redirecting to the same server, an absolute path suffices. Don't overcomplicate your redirects for nothing with $_SERVER variables.

As soon as the Location header is sent the browser will abort the current operation and fetch the page at the redirected location. This means that for all intents and purposes a location ('header: example.com') will have essentially the same effect as a die (). You can override this behaviour by using output buffering, or you can move the header() calls to lower down in your script. However you can't move them to after the print_redirect_unexpected call, as sending any output to the browser will cause all headers to be sent as well and you won't be able to send any more.
So basically, you need to turn on output buffering.

Related

PHP die() shows brief white screen

I'm using a redirect function to redirect visitors to a certain page when they don't have access to the current page. The function is as follows:
$user->redirect('www.google.com');
die();
The redirect function links to:
public function redirect($url="",$time=0) {
header("Refresh: $time; url=$url");
}
Whenever you get redirected you briefly see a white page followed by the page you get redirected to. I'm assuming the white page is caused by die().
I don't like it and I really want to get rid of this.
The problem is not related to the die() call, but that you are sending the wrong header to handle a redirection.
Instad of doing
public function redirect($url="",$time=0) {
header("Refresh: $time; url=$url");
}
do:
public function redirect($url) {
header("Location: $url", true);
}
Or even:
public function redirect($url, $temporal = false) {
header("Location: $url", true, $temporal ? 302 : 301);
}
With this you are sending a status code "301" or "302", to indicate that the redirection is either temporal, or a permanent. Defaulting to a permanent redirect, since temporals are very rarely useful (although in your case, being a redirection because of permissions, a temporary redirection might be in order)
(I also removed the default value for $url, because it doesn't make much sense to redirect to an empty url)
Instead of using a 'Refresh:' header, you can just use 'Location:'. This way, the page does not have to be refreshed and will probably result in your desired behaviour.
public function redirect($url="/") {
header("Location: $url");
}
edit: added default $url '/' so that if no url was given it redirects to homepage
I'm disapointed to the prev. posts. It is about the die() !
When sending a header the browser takes a little time to take action. Between this time the php process then calls die() before you are redirected. This is asyc. Location and Redirect
So it shows you a black page and then you/visitors get redirected.
Good: setting die() to end the process to avoid futher actions inside your program
Bad: The blank page first.
This is depending on your enviroment of your browser! E.g: a very slow workstation will show you this behavior and you have to care about. Imagin the browser does know about header redirections (Today it (mostly) doesnt exists anymore)
To give the browser a change to take action, use this:
function someaction() {
// ...
$user->redirect('www.google.com');
// which give the time for the browser
// without further execution of your code
return;
}
In this case the visitor stays as long on the current page until the browser knows about headers or the cpu is slow but will take action when it is able to take action.

Does PHP continue to execute after a PHP redirect?

I'm making a website that does a lot of PHP redirects depending on different scenarios.. Like so...
header("Location: somesite.com/redirectedpage.php");
I'm just trying to get a firm understanding of how the redirect works, for securities sake.
My question is, does PHP continue to execute after this header call?
For example... Would the echo still get executed in this bit of code?
function Redirect($URL)
{
header("Location: " . $URL);
}
Redirect("http://somesite.com/redirectedpage.php");
echo("Code still executed");
If so... Would me changing the Redirect function to this... make it the echo not execute but still redirect?
function Redirect($URL)
{
header("Location: " . $URL);
exit(1);
}
Redirect("http://somesite.com/redirectedpage.php");
echo("Code still executed");
I'm just trying to get a firm understanding of how the redirect works, for securities sake.
All the header() statement does is modify the headers your webserver (Apache, nginx, etc.) send to your browser. You've added a Location: header to the page, which tells the browser to redirect to that page. Everything else in the PHP script will execute, including your echo, but you probably won't see it because you are going to be redirected to a new location.
The header command doesn't interrupt the flow of your code. Even if that is encountered, your page is still downloaded by the browser, even if it isn't show. Consider 404 pages, which (despite being errors) are still processed by the browser (though they are rendered while redirects are not).
You can output a lot more headers than just Location headers with header, most of which you don't want to stop your code execution. If you want to stop code execution, you need to call exit explicitly.

!isset($_GET["sample"]) is not working as expected

I'm having trouble getting an !isset test working properly.
I tried a few different things but can't get it working as I expected.
Here is the scenario: if the get variable isn't set (i.e. someone visits the page directly and not to the page with the get variables in the url) then send them to another page.
This is what I tried:
if(!isset($_GET["e"])){$goToPage = 'Location: http://'.$_SERVER['SERVER_NAME'].'/';header($goToPage);}
if(!isset($_GET["k"])){$goToPage = 'Location: http://'.$_SERVER['SERVER_NAME'].'/';header($goToPage);}
I also tried this:
if(isset($_GET["e"])){}else{$goToPage = 'Location: http://'.$_SERVER['SERVER_NAME'].'/';header($goToPage);}
if(isset($_GET["k"])){}else{$goToPage = 'Location: http://'.$_SERVER['SERVER_NAME'].'/';header($goToPage);}
I know my variables are fine because if I echo the gets or assign them to variables, I get no problems:
$currentEmail = htmlspecialchars($_GET["e"]);
$currentKey = htmlspecialchars($_GET["k"]);
echo($_GET["e"]);
echo("</br>");
echo($_GET["k"]);
I also heard that by doing the check below, you can find out if someone came to the page by clicking a link. i.e. adding "a" instead of an actual get variable name. Does anyone know if that's true?
if(!isset($_GET["a"])){$goToPage = 'Location: http://'.$_SERVER['SERVER_NAME'].'/';header($goToPage);}
The code you provided works absolutely fine and as expected on my system (Apache 2.2 on Debian).
You may need to check whether your Location: header is actually being sent. I'm guessing you're sending some output before your header() call, which will mean your header won't be sent at all - your header must be the absolute first output, which means you can't even have a blank line before your <?php tag. Depending on your error reporting settings, you may not see a warning when this happens. Take a look at PHP header redirect not working.
The script does not stop after you issue a Location header! If you issue another Location header later in the same script, it's going to overwrite the previous one! exit after you set the header to prevent the rest of the script from executing.
if (!isset($_GET["e"]) && !isset($_GET["k"])) {
header('Location: http://' . $_SERVER['SERVER_NAME'] . '/');
exit; // <----- !!!
}

header location not redirecting at once, looking for alternative

I was writing a script where I have a redirect header in the end.
Then I added a redirect header in the middle if a specific condition would come up.
I was very surprised to notice that the last header("Location:http//mydomain.com") was the one that triggered. I thought that the header would automatically "jump" from the page, but it seems like it just keeps it in memory and goes through the whole page first.
Any ideas on what the "proper" way to "cut" the flow and change page is?
<?php
$specific_condition=true;
// I wanted this to be the end
if($specific_condition) header("Location: http://google.com/");
// But it still triggers following redirect
header("Location: http://bing.com/");
?>
Always call exit; right after your Location header:
if($specific_condition) {
header("Location: http://google.com/");
exit;
}
header() function by itself just collects the headers to be sent to the client. So it is not supposed to stop execution after any particular header, e.g. Location. But as long as it makes no sense to do something after you decided to redirect user - exit is used
you can use variable to hold location address
This way, you can also execude some code after new location is set.
$location = 'http://bing.com/';
$specific_condition=true;
if($specific_condition) $location = 'http://google.com';
//do something else
header("Location: " . $location);

Redirect based on referer's url

I am trying to redirect visitors to a site based on their referring url.
Here is the script:
php
$domain='blankds.com';
$referrer=$_SERVER['HTTP_REFERER'];
echo $referrer;
if (preg_match("/$domain/",$referrer)) {
header('Location: http://www.blackisgreen.org/page_1.php');
} else {
header('Location: http://www.blackisgreen.org/page_2.php');
};
Errors: I get a "Warning: cannot modify header" error because I am echoing $referrer before sending headers.
If I remove the echo the script does not work.
Any suggestions?
PHP is sending headers to the user requesting the page when you echo $referrer. The header function you are then calling attempts to modify these headers and affix a location redirect but cannot as the headers have already been sent along with the start of your page content.
To get around this problem, take a look at PHP's Output Control functions, especially ob_start(); which inserted at the top of your script should allow you to continue echoing the redirect location and allowing you to redirect at the same time.
Just as a note: Any output will auto-generate headers. If you want to redirect with headers you just need to comment out echo $referrer; If you need to see what referrer is going to which site for debugging purposes, just put it in the URL, the receiving page should ignore it.

Categories