Session superglobal array - php

I just noticed that session_destroy() does not seem to be working for me.
Testing PHP code looks like this:
session_start();
session_destroy();
$_SESSION['session'] = 'session started';
print_r($_SESSION);
But the display still shows
Array ( [session] => session started)
Surely this should throw an error as the SESSION variable now does not exist?

session_destroy destroys the saved session data - in most cases, that's the session file.
However, it doesn't affect the session variable itself.
Therefore, so long as you are in the same request, you can continue to use the $_SESSION superglobal with all its previous values. To completely destroy that, you should use:
foreach(array_keys($_SESSION) as $k) unset($_SESSION[$k]);
Or code to similar effect.
That said, it doesn't matter much - the session will be destroyed, and usually you only do this on logout pages that will only be displayed briefly before sending the user back to the homepage.

Related

Use of session_destroy() instead of unset($_SESSION['userName']) not working

I have used session_destroy in MVC pattern.
If I click logout link, it will redirect correct url but page disappears. It is displaying the below error in Firefox.
The page isn't redirecting properly
Firefox has detected that the server is redirecting the request for this address in
a way that will never complete.
This problem can sometimes be caused by disabling or refusing to accept cookies."
This is the function I'm using for logout.
Logout function:(Not working)
public function Logout(){
session_destroy();
$this->redirect('index.php?r=admin/login');
}
I have unset($_SESSION['userName']) the session variable. It is working fine. But session_destroy is not working in that place.
What is the reason for that?
Logout function:(working)
public function Logout(){
unset($_SESSION['userName']);
$this->redirect('index.php?r=admin/login');
}
you can use another way to remove session like:-
$_SESSION = array(); // define it with empty array and clear the session values
or use start the session again and then destroy
session_start();
session_destroy();
For more :- why session_destroy() not working
and for better understanding you can read #Chen Asraf answer
From the PHP documentation of session_destroy:
session_destroy() destroys all of the data associated with the current session. It does not unset any of the global variables associated with the session, or unset the session cookie. To use the session variables again, session_start() has to be called.
In order to kill the session altogether, like to log the user out, the session id must also be unset. If a cookie is used to propagate the session id (default behavior), then the session cookie must be deleted. setcookie() may be used for that.
So in order to truly get rid of the session, you also have to unset or override the $_SESSION superglobal, like you did before.

Can a new session be started after session_destory is called within a script?

I have the following basic logout script which I believe to be functioning strangely:
<?php
session_start();
$_SESSION['customerState'] = array("abbr"=>"TX","full"=>"Texas");
$_SESSION['agent']['url'] = "jmarston4";
$fart = isset($_SESSION['customerState']) ? $_SESSION['customerState'] : array();
$url = isset($_SESSION['agent']['url']) ? $_SESSION['agent']['url'] : '';
$_SESSION = array();
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
echo "Fart1: ";
print_r($fart);
session_destroy();
echo "<br>Fart2: ";
print_r($fart);
session_start();
echo "<br>Fart3: ";
print_r($fart);
$_SESSION['fart'] = $fart;
echo "<br>Fart4: ";
print_r($_SESSION['fart']);
#exit;
header('Location: https://'. $_SERVER['HTTP_HOST'] . '/' .$url);
This page redirects to the site homepage (index.php) with a referrer URL (mentioned as $url). This works just as it should. For testing sake, here is a screen shot of ALL of the code on index.php:
http://imgur.com/EmkRAh0
If I allow the exit; to process, the following is outputted to screen:
Fart1: Array ( [abbr] => TX [full] => Texas )
Fart2: Array ( [abbr] => TX [full] => Texas )
Fart3: Array ( [abbr] => TX [full] => Texas )
Fart4: Array ( [abbr] => TX [full] => Texas )
(or visually: http://imgur.com/A6WuRfx)
In this script (logout.php), I want to keep a single SESSION variable from the customers session (and not manually unset 100+ others) so I can pass it back to the homepage for internal purposes. To do this, the script does the following:
Set the SESSION variable 'fart' equal an array
A local variable is then set equal to the SESSION 'fart' before the entire SESSION is destroyed
The session data is cleared
The session cookie is deleted
the session is destroyed
The SESSION 'fart' is created and set back to the $fart array
the page redirects to the homepage.
QUESTION
By design, are PHP SESSIONS expected to behave this way? If so, how can one essentially destory a session (say for logout purposes) while maintaining pieces of session information collected during that user session.
Note: I am using SESSION arrays so passing in the URL for GET purposes is not applicable here.
Update Notes:
I changed the title of this question from "Are PHP sessions behaving according to spec?"
All of this works on the script itself, however, when I try and access $_SESSION['fart'] on the homepage, it is not set. I am able to set, manipulate or alter SESSION variables on the page at any point, INCLUDING after session_destroy() is called. For example, if I want to do the following:
...
session_destroy()
$_SESSION['eatmyshorts'] = "hello!";
echo $_SESSION['eatmyshorts']; // will display hello!
....
however, once the script (page) ends, anything relating to sessions (even $_SESSION['eatmyshorts'] in this case, is not available on any other page and disregarded.
If you call session_destroy, the stored session data is destroyed, $_SESSION is emptied, and the ‘session state’ is reset as before session_start was called. In that state, the data in $_SESSION exists just during runtime. Now if you call session_start after session_destroy, the session handling behaves exactly as if it where the first active session within the runtime: If the client request contains a syntactically valid session ID, it will use it for this session.
This all does work as expected.
However, what you haven’t taken into account is how sessions behave when you delete the session’s cookie containing the ID. Because when you sent the cookie to revoke the session ID for the client, the client won’t send a session ID along the next request and session_id will generate a new one. Since it’s a new session, $_SESSION is empty.
If you want to revoke the current session ID and generate a new session ID, use session_regenerate_id(true) and session_unset.
Once you call session_destroy the session is, well, destroyed and the server-side storage of the session data deleted. Manipulating the $_SESSION viariable after that has no effect as it's not "bound" to an actual session anymore (ie. the data you set don't get written to the session data storage when the script ends).
ALL of this works on the script itself
Then there is nothing wrong with the code you have provided (apart from the missing session_start(), but you said you put this in - you should edit your code above as people are replying based on it being an obvious error)
I tried your code above and confirm it works as stand alone.
To get help, you should explain or (ideally) show the rest of your code so it can be evaluated and the root cause of the issue discovered.
Try changing your bottom bit of code to this and tell us the outcome
echo "Fart1: ".$fart;
session_destroy();
echo "<br>Fart2: ".$fart;
session_start();
echo "<br>Fart3: ".$fart;
$_SESSION['fart'] = $fart;
//header('Location: /'); exit; <-- commented out
echo "<br>session: ".$_SESSION['fart'];
Although you had it working yourself, and are SURE that session_start() is present on the file which it redirects to and is at the top of the file BEFORE any HTML output, also try redirecting to the actual page name just to rule something else out, ie
header('Location: index.php'); exit; //or whatever filename is your homepage
Also to answer your other question about how to do this properly, how you do it is fine, as you set a var to the value, start the session again and set the $_SESSION to the var value.
You can access $_SESSION data directly, eg
$_SESSION['userlogin']['username'] = 'james';
//log me out from the session =
$_SESSION['userlogin']['username'] = '';

How to completely destroy session variables on logout

When I log a user out of an app I am building I use session_destroy();
But when I go back to the page, all session variables are still set.
How can I completely destroy all session variables and ultimately require a user to log back in again?
Here is my code:
session_unset(); // clears all session variables
$_SESSION = array();
session_destroy(); // deletes session id
Thanks
After using session_destroy(), the session cookie is removed and the session is no longer stored on the server. The values in $_SESSION may still be available, but they will not be on the next page load.
If you need to clear the values of $_SESSION, set the array equal to an empty array:
Of course, you can't access the values of $_SESSION on another page once you call session_destroy, so it doesn't matter that much.Still if you are concerned .
Try the following:
session_destroy();
$_SESSION = array(); // Clears the $_SESSION variable
you are not calling session_destroy() for sure, your code may be unable to access it.
Post more code so we could help you

PHP $_SESSION variable will not unset

sorry for a repetitive question, I've seen a few of these on this forum but none of the responses worked for me...
I am building a basic login using php sessions, which I'm new at...
login.php validates html login form and begins a session, setting variables: $_SESSION['login'] and $_SESSION['id],
then each page that requires a valid login uses require 'session.php'; which checks the $_SESSION['valid'] variable and redirects a user w/o proper login variable. The problem is when I logout neither session variable I've set will unset.
Right now my logout.php file uses about every method to destroy the variables that I've been able to find online and none will actually do it.
So whenever I log out, I can still access the 'private' pages.
Also note: I have tried it w/o a session name ex: session_start(); that didn't work so now I'm using session_start("user");
Also note: I am NOT using cookies.
Here are the files I mentioned:
login.php
$email=$_POST['email-log']; $pass=$_POST['password-log'];
$i=-1;
do
{$i++; $path="users/".$i.".json";
$file= file_get_contents($path);
$x=json_decode($file,true);
} while($x['email']!=$email);
$id=$i;
$truepass=$x['pass'];
$errors=0;
$hash=hash('sha256',$pass);
if($hash != $truepass){$errors=$errors+1;}
if($errors==0){
session_start("user");
$_SESSION['login']="valid";
$_SESSION['id']=$id;
header('Location: loginlanding.php');}
else{header('Location: front.php?error=y');}
session.php
session_start("user"); if($_SESSION['login'] !== "valid") {header('Location: front.php?needto=login');}
logout.php
unset($_SESSION); unset($_SESSION['login']); unset($_SESSION['id']); session_unset("user"); $_SESSION=array(); session_destroy("user"); header('Location: front.php?logged=out');
Any and all responses are welcome and I thank you in advance, also note, I am new to logins in general so any advice to beef up security is welcome also. I'm planning on making it more secure, but first I need to get this basic functionality up and running.
You should never unset($_SESSION).
The easiest way to clear the $_SESSION variable is $_SESSION = Array();
However, you can also iterate with unset:
foreach(array_keys($_SESSION) as $k) unset($_SESSION[$k]);
It's amazing how many things you're attempting to do after you've unset the only reference you had to the session in the first place. Directly from the manual:
Caution
Do NOT unset the whole $_SESSION with unset($_SESSION) as this will disable the registering of session variables through the $_SESSION superglobal.
http://php.net/manual/en/function.session-unset.php
You're unsetting $_SESSION so your unsets to the other arrays of the super global $_SESSION aren't registering, leaving them still in the browsers temporary cookies. Use session_unset() instead if you're trying to remove all session variables. Otherwise, don't unset the session global, but unset each individual value of it you want to remove.
My working example (notice that you must put start on the call)
<?php
session_start();
session_unset();
session_destroy();
header('location: ./');
?>

PHP & AJAX Sessions : Session variables different on AJAX page than on page called from

I have a login page than involved destroying a session and starting a new one. I have very inconsistent results between both Chrome and Firefox.
I am clearing the session using:
session_unset();
session_destroy();
session_start();
$_SESSION = array();
But variables in the session seem to still exist until I refresh the page and then they disappear. My second problem ontop of this is that crucial $_SESSION variables are different on ajax pages called from this login page. This is causing big problems and inconsistent results on ajax pages.
What is the best way to destroy a session and set it with fresh variables that will be available to ajax pages?
If you're using session cookies you have to "remove" them as well.
$cookie_params = session_get_cookie_params();
setcookie(
session_name(),
false,
strtotime('2000-01-01')
$cookie_params['path'],
$cookie_params['domain'],
$cookie_params['secure']
);
Of course the cookie will not be deleted by the browser until you sent the response.
The new session would be created on the next request.
PS: The manual states:
Only use session_unset() for older deprecated code that does not use $_SESSION.
I found:
session_unset();
session_destroy();
session_start();
$_SESSION = array();
To be very unpredictable and yielded varying results between browsers which is unusual for PHP.
To resolve I simply replaced it with:
session_start();
$_SESSION = array();
I know this doesn't completely clear and replace a session, but all I really needed was the session to be cleared. The fact that the session has the same session_id doesn't really matter in my scenario.
Hope this helps some people having the same mare as me!

Categories