Partially delete/destroy $_SESSION data? PHP - php

I am looking for a way to delete only certain amounts of SESSION data that is stored whilst preserving the session data associated with the user being logged on.
At the moment I am doing this by individual unset statements to the SESSION variables I want to delete.
However I was hoping there may be a more clever way to just delete a whole section of the SESSION array whilst preserving specific variables
e.g.
$_SESSION['username'];
$_SESSION['user_id'];
$_SESSION['ttl'];
The use case for this process would be:
User Logs In --> User performs task --> Once task is complete delete session data associated with task --> User is still logged in!
I had considered perhaps using a table in my Database monitoring logins, what are your opinions on that?
Thanks for your time!

There is no way to delete "whole section of the SESSION array whilst preserving specific variables".Instead of that you can use two dimensional array for a task and delete that array.
$_SESSION["task1"]["username"] = "name"
$_SESSION["task1"]["pass"] = "pass"
$_SESSION["task2"]["name"] = "name";
when task1 complete delete like
unset($_SESSION["task1"]);
now $_SESSION["task2"] still exist.

Well you could store all this volatile data inside another key:
$_SESSION['volatile'] = array(
'one' => 'value'
);
If you dnt want to do that you could use array comparison functions like:
// specify what keys to keep
$_SESSION = array_intersect_key($_SESSION, array('keepme1', 'keepme2', 'etc'));
//specify what keys to remove
$_SESSION = array_diff_key($_SESSION, array('deleteme1', 'deleteme2', 'etc'));
As far as the DB you could do that but its not necessary to accomplish your objective, and unless there are moving parts you didnt list in your original question id say you probably dont need to do anything that complex right now.

Structure your session data in a hierarchy:
$_SESSION['loggedIn'] = TRUE;
// Temporary session data
$_SESSION['temporary'] = array(
'temp_var1' => 'foo',
'temp_var2' => 'bar',
// ...
'temp_var99' => 'baz'
);
echo $_SESSION['temporary']['temp_var2']; // bar
// Remove all temporary session data
unset($_SESSION['temporary']);
echo $_SESSION['loggedIn'] ? 'yes' : 'no'; // yes

I will have to disagree with #sathishkumar, the following method destroys partially session variables.
public static function destroyPartial($keys)
{
if (session_status() === \PHP_SESSION_NONE) {
session_start();
}
if (!is_array($keys)) {
$keys = [$keys];
}
foreach ($_SESSION as $k => $v) {
if (in_array($k, $keys, true)) {
unset($_SESSION[$k]);
}
}
$recoveringSession = $_SESSION;
session_destroy();
session_start();
$_SESSION = $recoveringSession;
}
In the php docs for the session_destroy function, we can read this:
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.
So, the "trick" is to call session_start AFTER session_destroy.
Hope this helps.

Related

How to destroy a specific session in PHP if two sessions are already in use?

I am unable to destroy a specific session.
first session is started when logged in into website.
and the other is after the checkout page.
After the checkout page there is the order-status page.
And there I am using session_unset($_SESSION['SESSION____NAME']);
Help me I am Confused plz help me.....
You have to work with a session_id instead of a session name. You can find the answer here: https://stackoverflow.com/a/24965106/9592932. Just add a https://www.php.net/manual/en/function.session-destroy.php to the correct session.
As you describe in the question you are working with two sessions: "first session is started when logged in into website. and the other is after the checkout page."
So if i populate two sessions with the same variable name value:
// populate 2 sessions with identical keys
for ($n = 1; $n != 3; $n++) {
$id = 'session' . $n;
session_id($id);
session_start();
$_SESSION["value"] = 'we are in: ' . $id;
echo $id . ": " . $_SESSION["value"]."\n";
session_write_close();
}
print_r($_SESSION);
Produces:
session1: we are in: session1
session2: we are in: session2
Array
(
[value] => we are in: session2
)
If you unset($_SESSION['value']) you will only unset the 'value' from the second session and not the first session. To access the first session you have to:
// switch back to first session
// make sure previous session is closed
session_id('session1');
session_start();
print_r($_SESSION); // Array ( [value] => we are in: session1 )
unset($_SESSION['value']); // to unset 'value'
session_unset(); // to unset all values in session (does not take parameter)
session_destroy(); // to destroy the first session
you have use unset() function to unset specific session variable
here is the code
unset($_SESSION['SESSION____NAME']);
learn more about php session handling from here

Retrieve last item in Session::

I was wondering how i could retrieve the last instance in the Session named smartBacklinks.
Here is the code
if(Session::has('smartBacklinks'))
{
// if(Request::header('referer') === LAST ITEM IN SESSION[smartBacklinks] ARRAY)
Session::push('smartBacklinks', Request::header('referer'));
}
else
{
Session::put('smartBacklinks', [Request::header('referer')]);
}
Also how do i retrieve this from a blade template ?
You can retrieve 'smartBacklinks' from the session based on the key like so:
$value = Session::get('smartBacklinks');
Also, you may want to note that you'd use Session::push() for pushing into an array session value and use Session::put() to simply store an item in session.
Retrieving the value from blade:
I guess you could pass the variable just retrieved to the view from the controller like so:
return View::make('foo.bar', array('smartBacklinks' => $value));
then use it in blade like so:
Go back
Hope that helps.
I edited my code alot and it is now functioning. I still need to add a few tweaks to make it behave 100% as i need it
The code looks like this right now:
if(Session::has('smartBacklinks')){
// Get the last item in Session array
$slice = array_slice(Session::get('smartBacklinks'), -1, 1);
// Check if Request::header('referer') is equal to the $slide[0]
if(Request::header('referer') != $slice[0]){
// Check if Request::header('referer') is empty
if(Request::header('referer') != '') Session::push('smartBacklinks', Request::header('referer'));
}
// If session[smartBacklinks] is not set. - Set
}else {
Session::put('smartBacklinks', [Request::header('referer')]);
$slice = array_slice(Session::get('smartBacklinks'), -1, 1);
}
Session::save();
Then of course the last instance of the session array is
$slice[0]
The last thing i need to add is:
when "back button" is clicked, it should remove the last instance of the session array, and it should not push URL into the session
I need to make sure that the session is loaded correctly so i dont have to refresh the webpage to get the correct "back URL"
Thanks for the answer!

Why is my session not holding its data?

I've never run into this before but for some reason, when I am using AJAX to set a session variable, the session will not hold them.
Here is what I have:
session_start();
if(isset($_POST['selected'])){
$_SESSION['user']['theme'] = array ('selected' => true);
} // This should be now set with the value and it is for a time, but unsets
if(isset($_POST['theme'])){
$_SESSION['user']['theme'] = array('name' => $_POST['theme']);
} // So should this
What I am seeing when I do a print_r under both if constructs is only the $_SESSION['user']['theme']['name'] var and the other is not set. If I do a print_r just under the selected var, I can see it just fine. Somewhere, the key and value are disappearing for selected.
Why is this happening? I'm expecting to see both name and selected.
Like i said in my comment, you're overriding the array :)
session_start();
//changed it to unset if not in $_POST
$_SESSION['user']['theme']['selected'] = isset($_POST['selected']);
if(isset($_POST['theme'])){
$_SESSION['user']['theme']['name'] = $_POST['theme'];
} // and unset it too
else {
$_SESSION['user']['theme']['name']= "";
}
You need to start the session first
session_start();
if(isset($_POST['selected'])){
$_SESSION['user']['theme'] = array ('selected' => true);
}
And also check whether the $_POST values are not empty.And you need to unset the name in session then assign it like
if(isset($_POST['theme'])){
unset($_SESSION['user']['theme']['name']);
$_SESSION['user']['theme'] = array('name' => $_POST['theme']);
}
At the start of any page that sessions variables are accessed in any way, the first command must be a call to session_start();

What's best? Many small session values or one large one? PHP

I have about 15-20 permission settings that are loaded when a user logs in. These are each stored as a session with a value of 1 or 0.
I'm wondering, would it be better to have one session like $_SESSION['permissions'] with a value of: dothis:0,dothat:1,doanother:1, etc. (one large string) which I can explode and seperate later on with PHP, or would it be best to have all these as separate sessions with just a value of 1 or 0?
Rather than a string to parse, store them as an array in $_SESSION. This makes it much easier to modify individual permissions without having to do piles of string operations.
session_start();
$_SESSION['permissions'] = array();
$_SESSION['permissions']['dothis'] = TRUE;
$_SESSION['permissions']['dothat'] = FALSE;
$_SESSION['permissions']['doanother'] = TRUE;
Addendum
You might have figured this out already, but I thought I would add that it is easiest to interact with these via a few tiny functions. These will save a lot of typing (and typing errors), and make sure the values all end up as booleans.
function grant($permission) {
$_SESSION['permissions'][$permission] = TRUE;
}
function revoke($permission) {
$_SESSION['permissions'][$permission] = FALSE;
}
// Test if the user is allowed to do $permission
// FALSE if the permission isn't set
function user_can($permission) {
return isset($_SESSION['permissions'][$permission]) ? $_SESSION['permissions'][$permission] : FALSE;
}
The you can just call them as:
grant('dothis');
revoke('dothat');
if (user_can('doanother')) {
// congratulations you're allowed
}
I'd have an associative array that held all the permissions...
$_SESSION['permissions'] = array(
...
);

Have I understood sessions/multi-dimensional arrays properly?

Am I doing the following correctly?
I have an array, which I want to save to a session, so I can use it later in my web application:
$data = array(
"id" => $_POST["id"],
"r1" => $_POST["r1"],
"r2" => $_POST["r2"],
"r3" => $_POST["r3"]);
I save it to a session like this:
$_SESSION['settings'] = $data;
Now, I am not sure how to make use of this later in my application.
Do I do the following
$id = $_SESSION['settings']['id'];
$r1 = $_SESSION['settings']['r1'];
or do I do the following
$data = $_SESSION['settings'];
$id = $data['id'];
$r1 = $data['r1'];
or do I do something else?
Both those methods are perfectly valid ways of doing it. It's probably worth putting some defensive coding in there however.
eg.
$id = "";
if (ISSET($SESSION["settings"]) && ISSET($SESSION["settings"]["id"])
{
$id = $SESSION["settings"]["id"];
}
You can do both as $_SESSION['settings'] points to an array, the two expressions will be identical:
// The expression...
$val = $_SESSION['settings']['id'];
// ... is an internal shorthand for ...
$tmp = $_SESSION['settings']; // $tmp never exist - just to aid explanation.
$val = $tmp['id'];
Don't forget to use session_start(); before setting/using variables.
Then set the variables as you did. Not 100% sure, but both ways should work.
When you finish working with session, dont forget to destroy it session_destroy();.
Do whatever you need to solve your problem. In your case, both ways are acceptable of working with sessions. If I were you, I would choose the first example when only need to acces 1 or 2 elements from the session and the secon example to access more than 2 (in order to type less ).

Categories