Weird header("Location:"); error - php

I've done tons of redirects using PHP's header function. This one has stumped me.
On my dashboard controller, I check whether or not the $_SESSION['loggedin'] is set. If it's not set, I want to send the user back to the main page. However, I keep getting the "too many redirects" error, even though I only have it set once. Can anyone help me out? Thanks for the help in advance!
Here's my code -
function index() {
if(!isset($_SESSION['loggedin'])) {
header("Location: ./");
} else {
die("The user is logged in.");
}
}

./ means "here", so yes, you're redirecting in a circle. You probably mean /, the root.
The Location header field should really contain a complete, absolute URL though. So you should redirect to http://example.com/. Relative URLs just happen to be (incorrectly) accepted by some browsers.

This is because you just refresh the page. It means the user isn't redirected to different URL, he stays where he were.
You're using wrong path for Location header. ./ is equal to . which is a relative path and means current path. Certainly, you want to use / which is absolute path, ie. it's related to domain's root.

I would use absolute paths it will reduce possible errors.

You might need to use global to access the session variables in your case.

Related

PHP Header Location: ../location vs $_SERVER[DOCUMENT_ROOT]/location

So, I made a simple PHP login, but when I tried to redirect like this:
$path = $_SERVER["DOCUMENT_ROOT"];
header("Location: $path/admin/index.php");
it seemed like it did nothing, but after I refreshed the page I was logged in.
After I changed my code to this:
header("Location: ../admin/index.php");
it works.
Could someone please explain this to me?
Ps. sorry for my bad english
The header is sent to the browser, so it is not an internal server maneuver. And with it not being an internal redirect, you don't deal with internal paths. When you use DOCUMENT_ROOT you will get the internal server path to the directory where your files are located.
If you want to reference the root of the site as a URL, just use /.
header("Location: /admin/index.php");
header("Location: /"); # go to homepage, for example
Your .. worked because you probably were on a subdirectory, and .. was translated to the parent directory which is where admin is.
$_SERVER["DOCUMENT_ROOT"];
returns path like /var/www/html/yourfolder/, but you have to redirect to website.com/yourfolder/ or localhost/yourfolder/.
hence that won't work.
Have you tried printing the value of $path?
the value of $path is relative to the actual file location
e.g. $path = '/c/inetpub/sites/example/main/'
You probably wanted something like '/c/inetpub/sites/example/' or '/c/inetpub/sites/example/main/..'

Why won't my $_SESSION variable change for each field [duplicate]

How do I resolve the problem of losing a session after a redirect in PHP?
Recently, I encountered a very common problem of losing session after redirect. And after searching through this website I can still find no solution (although this came the closest).
Update
I have found the answer and I thought I'd post it here to help anyone experiencing the same problem.
First, carry out these usual checks:
Make sure session_start(); is called before any sessions are being called. So a safe bet would be to put it at the beginning of your page, immediately after the opening <?php declaration before anything else. Also ensure there are no whitespaces/tabs before the opening <?php declaration.
After the header redirect, end the current script using exit(); (Others have also suggested session_write_close(); and session_regenerate_id(true), you can try those as well, but I'd use exit();)
Make sure cookies are enabled in the browser you are using to test it on.
Ensure register_globals is off, you can check this on the php.ini file and also using phpinfo(). Refer to this as to how to turn it off.
Make sure you didn't delete or empty the session
Make sure the key in your $_SESSION superglobal array is not overwritten anywhere
Make sure you redirect to the same domain. So redirecting from a www.yourdomain.com to yourdomain.com doesn't carry the session forward.
Make sure your file extension is .php (it happens!)
Now, these are the most common mistakes, but if they didn't do the trick, the problem is most likely to do with your hosting company. If everything works on localhost but not on your remote/testing server, then this is most likely the culprit. So check the knowledge base of your hosting provider (also try their forums etc). For companies like FatCow and iPage, they require you to specify session_save_path. So like this:
session_save_path('"your home directory path"/cgi-bin/tmp');
session_start();
(replace "your home directory path" with your actual home directory path. This is usually within your control panel (or equivalent), but you can also create a test.php file on your root directory and type:
<?php echo $_SERVER['SCRIPT_FILENAME']; ?>
The bit before 'test.php' is your home directory path. And of course, make sure that the folder actually exists within your root directory. (Some programs do not upload empty folders when synchronizing)
you should use "exit" after header-call
header('Location: http://www.example.com/?blabla=blubb');
exit;
I tried all possible solutions, but none worked for me! Of course, I am using a shared hosting service.
In the end, I got around the problem by using 'relative url' inside the redirecting header !
header("location: http://example.com/index.php")
nullified the session cookies
header("location: index.php")
worked like a charm !
I had the same problem. I worked on it for several hours and it drove me crazy.
In my case the problem was a 404 called due to a missing favicon.ico in Chrome and Firefox only. The other navigators worked fine.
I was having the same problem. All of a sudden SOME of my session variables would not persist to the next page. Problem turned out to be ( in php7.1) you header location must not have WWW in it, ex https://mysite. is ok, https://www.mysite. will lose that pages session variables. Not all, just that page.
When i use relative path "dir/file.php" with in the header() function in works for me.
I think that the session is not saved for some reason when you redirect using the full url...
//Does retain the session info for some reason
header("Location: dir");
//Does not retain the session for some reason
header("Location: https://mywebz.com/dir")
I had a similar problem, although my context was slightly different.
I had a local development setup on a machine whose hostname was windows and IP address was 192.168.56.2.
I could access the system using either of:
http://localhost/
http://127.0.0.1/
http://windows/
http://192.168.56.2/
After logging in, my PHP code would redirect using:
header('http://windows/');
If the previous domain name used to access the system was not windows, the session data would be lost. I solved this by changing the code to:
header('http://'.$_SERVER['HTTP_HOST'].'/');
It now works regardless of what local domain name or IP address the user puts in.
I hope this may be useful to someone.
I ran into this issue on one particular page. I was setting $_SESSION values in other pages right before redirecting and everything was working fine. But this particular page was not working.
Finally I realized that in this particular page, I was destroying the session at the beginning of the page but never starting it again. So my destroy function changed from:
function sessionKill(){
session_destroy();
}
to:
function sessionKill(){
session_destroy();
session_start();
}
And everything worked!
This stumped me for a long time (and this post was great to find!) but for anyone else who still can't get sessions between page redirects to work...I had to go into the php.ini file and turn cookies on:
session.use_cookies = 1
I thought sessions worked without cookies...in fact I know they SHOULD...but this fixed my problem at least until I can understand what may be going on in the bigger picture.
I've been struggling with this for days, checking/trying all the solutions, but my problem was I didn't call session_start(); again after the redirect. I just assumed the session was 'still alive'.
So don't forget that!
Nothing worked for me but I found what caused the problem (and solved it):
Check your browser cookies and make sure that there are no php session cookies on different subdomains (like one for "www.website.com" and one for "website.com").
This was caused by a javascript that incorrectly used the subdomain to set cookies and to open pages in iframes.
KEY POINT'S
Do not start a session on the return page.
Don't use session variable and not include header.php which user session variable
Just make a link go to home page or profile page after insert payment info and status
I had the same problem and found the easiest way.
I simply redirected to a redirect .html with 1 line of JS
<!DOCTYPE html>
<html>
<script type="text/javascript">
<!--
window.location = "admin_index.php";
//–>
</script>
</html>
instead of PHP
header_remove();
header('Location: admin_login.php');
die;
I hope this helps.
Love
Gram
If you are using session_set_cookie_params() you might want to check if you are passing the fourth param $secure as true. If you are, then you need to access the url using https.
The $secure param being true means the Session is only available within a secure request. This might affect you locally more than in stage or production environments.
Mentioning it because I just spent most of today trying to find this issue, and this is what solved it for me. I was just added to this project and no one mentioned that it required https.
So you can either use https locally, or you can set the $secure param to FALSE and then use http locally. Just be sure to set it back to true when you push your changes up.
Depending on your local server, you might have to edit DocumentRoot in the httpd-ssl.conf of the server so that your local url is served https.
Another possible reason:
That is my server storage space. My server disk space become full. So, I have removed few files and folders in my server and tried.
It was worked!!!
I am saving my session in AWS Dynamo DB, but it still expects some space in my server to process the session. Not sure why!!!
ini_set('session.save_path',realpath(dirname($_SERVER['DOCUMENT_ROOT']) . '/../session'));
session_start();
Too late to reply but this worked for me
To me this was permission error and this resolved it:
chown -R nginx:nginx /var/opt/remi/php73/lib/php/session
I have tested a few hours on PHP and the last test I did was that I created two files session1.php and session2.php.
session1.php:
session_start();
$_SESSION["user"] = 123;
header("Location: session2.php");
session2.php:
session_start();
print_r($_SESSION);
and it was printing an empty array.
At this point, I thought it could be a server issue and in fact, it was.
Hope this helps someone.
Verify that your session is not Strict. If it is, when you come back, like coming back from Stripe, it regenerate the session.
Use This:
ini_set('session.cookie_samesite', 'Lax');
I also had the same issue with the redirect not working and tried all the solutions I could find, my header redirect was being used in a form.
I solved it by putting the header redirect in a different php page 'signin_action.php' and passing the variables parameters through I wanted in url parameters and then reassigning them in the 'signin_action.php' form.
signin.php
if($stmt->num_rows>0) {
$_SESSION['username'] = $_POST['username'];
echo '<script>window.location.href = "http://'.$root.'/includes/functions/signin_action.php?username='.$_SESSION['username'].'";</script>';
error_reporting(E_ALL);
signin_action.php
<?php
require('../../config/init.php');
$_SESSION['username'] = $_GET['username'];
if ($_SESSION['username']) {
echo '<script>window.location.href = "http://'.$root.'/user/index.php";</script>';
exit();
} else {
echo 'Session not set';
}
?>
It is not a beautiful work-around but it worked.
For me the error was that I tried to save an unserialisable object in the session so that an exception was thrown while trying to write the session. But since all my error handling code had already ceased any operation I never saw the error.
I could find it in the Apache error logs, though.
Just for the record... I had this problem and after a few hours of trying everything the problem was that the disk was full, and php sessions could not be written into the tmp directory... so if you have this problem check that too...
For me, Firefox has stored session id (PHPSESSID) in a cookie, but Google Chrome has used GET or POST parameter.
So you only have to ensure that the returning script (for me: paypal checkout) commit PHPSESSID in url or POST parameter.
After trying many solutions here on SO and other blogs... what worked for me was adding .htaccess to my website root.
RewriteEngine on
RewriteCond %{HTTP_HOST} ^yoursitename.com$
RewriteRule ^.*$ "http\:\/\/www\.yoursitename\.com" [R=301,L]
If you're using Wordpress, I had to add this hook and start the session on init:
function register_my_session() {
if (!session_id()) {
session_start();
}
}
add_action('init', 'register_my_session');
First of all, make sure you are calling session_start() before using $_SESSION variable.
If you have disabled error reporting, try to turn in on and see the result.
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
The most common reasons that aren't mentioned in #dayuloli's answer:
Disk space problem. Make sure your disk space is not full, you need some space to store session files.
Session directory may not be writable. You can check it with is_writable(session_save_path())
I was having the same problem and I went nuts searching in my code for the answer. Finally I found my hosting recently updated the PHP version on my server and didn't correctly set up the session_save_path parameter on the php.ini file.
So, if someone reads this, please check php.ini config before anything else.
Make sure session_write_close is not called between session_start() and when you set your session.
session_start();
[...]
session_write_close();
[...]
$_SESSION['name']='Bob'; //<-- won't save
If you are using Laravel and you experience this issue, what you need is to save your session data before redirecting.
session()->save();
// Redirect the user to the authorization URL.
header('Location: ' . $authorizationUrl);
exit;
Now that GDPR is a thing, people visiting this question probably use a cookie script. Well, that script caused the problem for me. Apparently, PHP uses a cookie called PHPSESSID to track the session. If that script deletes it, you lose your data.
I used this cookie script. It has an option to enable "essential" cookies. I added PHPSESSID to the list, the script stopped deleting the cookie, and everything started to work again.
You could probably enable some PHP setting to avoid using PHPSESSID, but if your cookie script is the cause of the problem, why not fix that.
I fixed this problem after many days of debugging and it was all because my return URL coming from PayPal Express Checkout didn't have a 'www'. Chrome recognized that the domains should be treated the same but other browsers sometimes didn't. When using sessions/cookies and absolute paths, don't forget the 'www'!

PHP header location absolute URL

I came across an issue where an absolute path set in header location wouldn't work but pointing to the file itself did. This only affected a few customers. One of them was nice enough to try connecting through a VPN which made the header location work.
Didn't work:
header('Location: http://www.example.com' . $_SERVER['PHP_SELF']);
Works:
header('Location: ' . $_SERVER['PHP_SELF']);
Can anyone shine some light on this?
Thanks
Your affected customers are not able to resolve the http://www.example.com (or whatever it actually is) URL for some reason. You can verify this by having them just try and visit the http://www.example.com by manually typing it in the browser location bar. That should fail too.
This can happen you have a site that is available under a number of domains, or directly by the IP address. Even www / non-www versions can make this happen. They hit the site at one domain or IP address that works for them, and then you try and redirect them to a URL they can not resolve. This explains why redirecting to just the path works, but an absolute URL doesn't.
If they can reach http://www.example.com in the browser, but not by redirect, ask them to blow out the browser cache.
Also always exit the script afterwards because otherwise in my experience in certain circumstances code that comes after the redirect might still be executed. So a good example would look like this:
header("location:http://www.example.com/path/to/myfile.php");
exit;
Often you would use a server variable for this case:
$url = $_SERVER["HTTP_HOST"]."/path/to/myfile.php";
header("location:".$url);
exit;
Cheers!
Link answer: https://tousu.in/qa/?qa=1091514/

Fix a redirect loop?

I have the following code in my index.php page:
<?php include("/includes/widgets.php") ?>
And in my widgets.php page:
<?php
header("Location: /");
?>
What I want to achieve with this is to redirect it if the user visits it, but allow it for including.
But I get the following error:
The webpage has a redirect loop
How can I fix/prevent the redirect loop, but still redirect the user and not the server.
Place the widgets.php file in a folder not accessible to HTTP clients. I.e on apache webserver, either put it above your document root (into it's parent) or use .htaccess file to block users from it.
e.g.
deny from all
I think I know what you need :)
Change code index file to next
define("IS_INDEX", true);
include("/includes/widgets.php"
Change code for widgets.php to next
if (!defined("IS_INDEX")) {
header("Location: /");
exit();
}
The issue is you are redirecting back to the same page, which then redirect again, and again, and again.
An easy fix would be to wrap the redirect in an if, and only redirect if they aren't already on the index page; but this is just patching what looks like an architectural problem.
Something like:
if (ltrim($_SERVER['REQUEST_URI'], '/') != 'index.php')
header('Location: index.php');
One way is to check if __FILE__, which is the file loaded, regardless of included or not matches up with the file requested which is in $_SERVER['REQUEST_URI'] (or $_SERVER['PHP_SELF']).
I use this on our development site in a page that is usually included to get the output as debugging.
if(basename($_SERVER['PHP_SELF'])===basename(__FILE__)){
//do some debugging
}
Typically you wouldn't use basename, but this is on a non-public facing development site and the file has a pretty unique name so I'm not worried about the file being included with another file with the same name or anything.
One possible way is to add a parameter to the redirection, e.g.
if (!$_REQUEST['redirect'])
header("Location: /ìndex.php?redirect=1");
That way redirection can happen only once.
Another way is to stop redirection if the user already is on the /. I´d suggest to combine both.

To understand PHP's header()

Where do you use the command header()?
I have the following code at handlers/handle_login.php. The user has gone to the site from index.php which is the starting place.
if(!$logged_in){
header("Location: index.php");
die("You are not logged_in");
}
If if-clause is true, I get a 404 error, since the header puts me to to handlers/index.php, instead of index.php.
While I agree with nilamo and earl, I hope I can give a bigger picture:
Using relative paths can have very strange effects depending on where the browser
'thinks' it is in your site hierarchy. For example, assume the site has an index file '/index.php' but is configured to accept module and action in the URI path. You may very well have a url that looks like:
http://www.yoursite.com/forms/contact/
From this situation, returning a header like:
header("Location: index.php");
may very well cause the browser to try to request
http://www.yoursite.com/forms/contact/index.php
which is obviously not what you want. For this reason, it's generally better to use '/index.php' as recommended above, or even better use the fully qualified URL when possible.
Hope this helps.
Set the location to the complete URL of the index.php, not just the filename. According to php.net, this is the right way to do it, don't use relative paths. Here is an example:
if(!$logged_in){
header("Location: http://exampledomain.com/index.php");
die("You are not logged_in");
}
Try using '/':
if(!$logged_in){
header("Location: /index.php");
die("You are not logged_in");
}
Without a slash, it is assumed that you're referring to something in the current directory. By sticking that slash at the front, you're explicitly referring to the file at the root of the site. Since the page is 'index.php', you could just as easily use "header('Location: /')".

Categories