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.
Related
Dears,
I create a function that permits to redirect the user to a specific URL. The function is named redirect and user the header function:
public function redirect($url, $code = null)
{
if($code == 301){
header("HTTP/1.1 301 Moved Permanently");
}
header('Location: '.Router::url($url));
die();
}
I use it to protect some pages to be reachable for a none authenticated users. I put a condition, permits to check if user is logged, if not will be redirected to the login form:
if(!$this->Session->isLogged()){
$this->redirect('users/login');
}
The function isLogged is:
public function isLogged()
{
return isset($_SESSION['User'][0]->id);
}
I tried to do the same things, for BO admin pages and it works. But I need to protect the front pages too. The problem is when I try to access to a front-page, I'm redirect to the login form, but I got the ERR_TOO_MANY_REDIRECTS error on my Chrome browser.
I tried to delete cookies, but I have the same problem. When I try to ignore the following line, I can see my login form:
if(!$this->Session->isLogged()){
$this->redirect('users/login');}
You should not attempt to redirect to login in case you are already on that page.
if(!$this->Session->isLogged() && !$this->isLoginPage()){
$this->redirect('users/login');}
}
PHP raises this error in two main cases:
Infinite redirecting: you're probably invoking your mentioned function for an infinite number of times
Too many redirects in a row: the "Header" native PHP's function handle only one header per instance.
In a nutshell: the error related to your case is quite surely related to an infinite redirect, otherwise there could be other redirects invoked moreover the wanted one in the page where you're calling your function.
The redirect() helper function in the helper file does not work in Laravel.
Here is my code helpers.php
if (! function_exists('license_check')) {
function license_check(){
//This does not work, returns a blank page
return redirect()->route('loginlicense');
//This does not work, returns a blank page
return \Redirect::route('loginlicense');
//This work but it prints on the browser before redirecting
echo \Redirect::route('loginlicense');
echo redirect()->route('loginlicense');
//This work but it prints on the browser before redirecting
die(\Redirect::route('loginlicense'));
die(redirect()->route('loginlicense'));
//The below works. But I would like to pass laravel flash sessions with `Laravel's with('status', 'My mesage')`
$url = route('loginlicense');
header("Location: ".$url);
exit();
}
}
license_check();
Why am I getting a blank page instead of being redirected to the url specified while using Redirect:: or redirect().
Same Issue
I had this issue - and did not want every controller action to worry about what this helper could deal with, so I figured that "Needs to be returned to the browser" could be accomplished by an echo and exit;
My Solution
// Redirect to the login?
if (empty($admin) || empty($token)) {
// I have to echo the redirect in order to return the response from here.
echo redirect('/admin/login');
exit;
}
More Explanation
Redirect - set headers only, before output.
When you redirect in PHP, you are only setting headers - that's what the redirect() function will do. This function derives to a Redirect Facade method to(), which returns a laravel RedirectResponse. When "echoing" it should only give back a response with headers and no body.
This means you cannot start outputting before the redirect. Remove any var_dumps, included template/view files, or other echos! Even a blank string or line space in a template file can ruin this.
Remember, you are server-side!
You would not be able to (due to errors - see headers already sent), or want to, redirect in the middle of a template file, because PHP is the language that is processed on the server side - so just once... if you need to be redirecting within a rendered view (probably based on some condition), use javascript!
More about "echo"
Because we are doing an echo redirect(), you may be scared of what the echo means. It is just sending back the full response (with only headers if done right!)
Sometimes I think that it is harder for people to realize that the only way PHP can ever send back a response (headers and the body) is through an echo (or similar outputting functions eg. printf, var_dump, etc), but most frameworks do not make you aware of this, so your only experience with echo is inside of templates.
Ps. Some frameworks utilize output_buffering to store the "echo" results in a buffer for last minute processing before sending everything.
Test it in your network tab of your browser
If you are doing it right, in the network tab of the browser, you will see a status code of 302 and the response section will say "Failed to load a response..." because it was redirecting.
If you are seeing the URL or anything else in the response tab, eg. the url , it is likely because you are sending out content via a var_dump, including a template file, or another echo that is creating a response body. Try using your browser network tab and preserve the log to see what is happening.
Even sending an empty string or line break counts as a response body (hence blank page). Typically you should get warnings about trying to set headers after some of the response body has already been sent in PHP. Basically, you should not be including a template or echoing anything out before a redirect. Your logic should process the redirect first thing!
The exit is there to make sure it does not go on to include your view or echo more things out!
It's because invoking redirect() by calling it inside a function does not work. Just like what Quezler said, it needs to be returned to the browser.
You can handle redirect in the controller. Helper function return a boolean value, or maybe throw exceptions.
helper.php
if (! function_exists('license_check')) {
function license_check($id) {
if($id == 2){
return true;
} else {
return false;
}
}
}
HomeController.php
use Session;
$check_lic = license_check(2);
if($check_lic) {
session()->flash('success', 'Your message!');
return redirect()->route('loginlicense');
} else {
session()->flash('error', 'you have not purchase licence!');
return redirect()->back();
}
I have a script which logs some stuff into a database. At the start of the script I have some code which tests a session to determine if a user is logged in - and if not - redirects them to the front page.
if (!$_SESSION['user']['loggedin'] || $_SESSION['user']['access_level'] < ACCESSLEVEL_ACOUNT_MANAGER) {
redirect('../index.php');
}
But - I'm getting odd entries into the database that are coming from this script. That I know for sure. I've set up a routine that emails me when an entry is made telling me the values of those sessions - and they're blank.
If a POST does not come from a browser - will the redirect be ignored and will the rest of the script be processed?
--
Edit - here's the redirect function (prior to me adding the exit) which was the culprit.
function redirect($url) {
session_write_close();
if (true || headers_sent()) {
print "<script langauge=\"JavaScript\">window.location='$url';</script>";
} else {
header("Location: $url");
}
header("Location: $url");
}
If a POST does not come from a browser
The type of client that makes an HTTP request is largely irrelevant.
The significant part here is that $_SESSION['user']['loggedin'] is empty, so the if passes and the redirect function is called.
will the redirect be ignored
The redirect function will be called.
The client may or may not follow the instruction from the server to request a different URL instead.
and will the rest of the script be processed?
The behaviour will be the same as for a browser.
There's nothing in the question to tell us what the redirect function does.
It might exit, in which case anything after the if statement will not be processed.
It might not.
… but the result will be the same for any kind of HTTP client. Browsers are not a special case.
I'm new to PHP and am wondering how to handle redirection in case of error.
I have a script which calls a function:
$cart_object->Go2Server();
$echo 'error';
Now, if all goes well the script will redirect the user to another url. However, if something goes wrong the page refreshes and i see the error message. Ie, the function returns.
What I'm not sure of is how to redirect the user somewhere else if the function returns. If i have the following, the redirect_to_error is sometimes called when there is no error.
$cart_object->Go2Server();
redirect_to_error();
EDIT - sorry I should add, if the script dies after the redirect, how can it return a value?
The header function can take care of this
http://php.net/manual/en/function.header.php
Example :
header("Location: http://www.google.com");
exit;
You'll need to return a bool value from the function and check the value with an if statement in order to redirect to a specific page.
In your Go2Server function, consider having it return a boolean variable that indicates whether or not the headers have been set correctly to redirect the user. That is, if Go2Server works, return true, otherwise return false.
Then, run your redirect_to_error function if the boolean is false. To redirect someone, use the header function. e.g.
header('Location: www.example.com');
Is the redirect taken place in the $cart_object->Go2Server(); function?
If so is there an exit() or die() after the redirect?
The script continues when doing a redirect that's why you always need to end the script execution after redirect.
It would have been helpful if you'd shown the HTTP headers for successful and failed operations.
It sounds like you may be trying to issue a HTTP redirect (i.e. a 302 response code) after the page output has started (at which point the headers cannot be changed). If you've got your error reporting set up correctly you should see lots of 'headers sent' in your logs.
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.