I thought about some helper to manage session variables on my development localhost.
I would like to read,change and delete session variables from ALL vhosts on my machine.
As far i know, from PHP i can access only current host session variables, which will be populated to $_SESSION variable, after call to session_start. That's not enough for my needs.
After some research (ex. Access active sessions in PHP) i found solution :
Load all files from php session directory
Use session_decode to load data to $_SESSION variable
Read/change/delete some variables
Use session_encode to encode my session back to file
There is any better method to do that?
Maybe there is already dedicated tool for that task?
EDIT:
Another solution which i now currenty use is just enable debugger in IDE for desired project, and use watches/stack window to edit session.
EDIT2:
I dont want any project-specific solution like storing session data in database. This should work "out-of-the-box", for any project.
For better understanding, use example:
In magento admin panel grid filters are stored in session variables.
When you enable broken filter there is an error page, and you can't easily disable this filter without removing session cookie, or setting debugger for it.
I spend some time once with a script that programatically "expires" server sessions to obtain info about user inactivity. On that occasion, I had a database with session_ids to transverse, but it can be done with directory listing (note that are php's compilation specific advices on code)
//Preserve runtime variable
$pre_config = ini_get('session.use_cookies');
//Check previous session_start();
if($previous_sid = session_id()){
//close and save current session
session_write_close();
}
//To determine where php session files are stored, see http://stackoverflow.com/questions/4927850/location-for-session-files-in-apache-php
if(($save_path = session_save_path()) === ''){
// PHP compilation specific
// There are diferences between CLI (saves in sys_get_temp_dir()) and mod_php (where session_save_path() works) on Fedora 12
$save_path = '/var/lib/php/session/';
session_save_path('/var/lib/php/session/');
}
//Avoid new cookies from other session_start()
ini_set('session.use_cookies', false);
//Do the magic
if ($handle = opendir($save_path)) {
while (false !== ($entry = readdir($handle))) {
if (strpos($entry, 'sess_') === 0) {
$session_id = str_replace('sess_' , '', $entry);
session_id($session_id);
session_start();
//Do whatever you want with this session, using $_SESSION
session_write_close();
}
}
closedir($handle);
}
//Restore previous configuration
ini_set('session.use_cookies', $pre_config);
//Restore previous session
if($previous_sid) {
session_id($previous_sid);
session_start();
}
I do not recommend running this code on client request. Remember that session_start block script execution while "session id" is in use on another request. And I think that is not recommended to run it by a CLI script, because PHP embedded on WebServers and PHP CLI uses different environment and configurations (besides the fact that the running user of a PHP CLI must be the same user that runs the WebServer to prevent permission deny).
I think that the ideal solution is to trigger requests to this script with a HTTP GET periodically (by linux crontab or similar), of course this solution depends on final use been planned. If HTTP request trigger can be done, the part of the code that saves previous settings and session can be eliminated.
Related
session_start();
$_SESSION['user_id'] = 0;
session_regenerate_id();
$_SESSION['user_id'] = 5;
After running the following code, why is my $_SESSION['user_id'] still 0 when I access it later? Am I misunderstanding how session_regenerate_id() is supposed to work? Or is it an issue that I need to address elsewhere?
I can see that two session files have been created in C:\xampp\tmp, but I don't understand why the old file is being used.
My example is me trying to understand why I could not access $_SESSION['user_id'] that I would set after running session_start and session_regenerate_id at the very beginning of my .php file:
session_start();
session_regenerate_id();
$_SESSION['user_id'] = 9; // i am unable to access this because my app is using the old file
Appreciate any help with this.
Didn't you check the session.use_trans_sid php.ini option?
In my php.ini, I have session.use_trans_sid=0 and another suggestion mentioned i do the following as well session.use_strict_mode=1. Still not working after these two edits.
Note: i assume that they are 2 different https/http calls (the two
codes starting with session_start() ... ) Can you see what all is
stored in the 2nd file in the Session before and after you do the
session_start? you can do a print_r($_SESSION) and do it before you
regenerate as well I bet there is some code in between your lines that
you haven't shared, is doing something to the session_start
I actually simplified my code down to the example in my post, and you can see it here. This way, we are not worried about any other code.
I cleared my tmp folder and ran the code. Here are the resulting files with session_regenerate_id() commented out:
First File - https://pastebin.com/mBhQCrF3
addrelease.php output is 9 for 'user_id'
I commented out the line that sets the 'user_id' to 9 to see what happens next time I log on
Second File - https://pastebin.com/QNJ6S7sY
As expected, a new file with 8 as 'user_id'
Now I will clear the tmp folder (and restart server) again and do the same with session_regenerate_id() in the code. More specifically, this is what loginuser.php will run now:
session_start();
$_SESSION['user_id'] = 8;
session_regenerate_id();
$_SESSION['user_id'] = 9;
$response['success'] = true;
$response['username'] = "test";
echo json_encode($response);
exit;
This time, since we regenerate the id, there should be two files after loginuser.php is finished. I can't tell which one was created first, but we can see that one has 'user_id' set as 9 while the other has 'user_id' at 8:
File 1: https://pastebin.com/ba1vAmjd
File 2: https://pastebin.com/H9kDfdvt
After this, the output given by addrelease.php once it's finished is 8.
With the following change to loginuser.php, we can also get an idea of what 'user_id' is before it exits and addrelease.php runs the second session_start() call:
session_start();
$_SESSION['user_id'] = 8;
session_regenerate_id();
$_SESSION['user_id'] = 10;
$response['message'] = $_SESSION['user_id'];
$response['success'] = false;
$response['username'] = "test";
echo json_encode($response);
exit;
I clear tmp folder and restart servers again. This time, 'user_id' output is 10. So we can see that loginuser.php is using the correct file, while addrelease.php does not:
File 1: https://pastebin.com/7MpRMbge
File 2: https://pastebin.com/p6RUxH8F
Hopefully I have supplied enough in response to your comment.
EDIT: Also, I don't know if this is significant, but there is a another activity (dashboard activity) between my login activity and my add release activity that does not trigger a .php file.
I think i know the core issue and have the solution as well.
From the json_encode, i assume that some frontend is querying these php files and a json response is sent. So, the session is being written to multiple times.
After writing to the session, IN EVERY FILE that you write sessions to, but PER HTTP/HTTPS request, please do an explicit session_write_close() https://www.php.net/manual/en/function.session-write-close.php .
So, what i mean is that let us assume you have frontendpage1.php that has the html for the user. If you are writing to sessions in this file, do a session_write_close() at the end. Further, if, as a result of an ajax call or something, you have file1.php, file2.php and file3.php used, where they are all writing to the session, do session_write_close() at the end of the last write of the session.
I remember reading that this good practice when sessions are written to frequently.
I had a similar issue with sessions and this worked well
Remember to do a session_start() at the start of each unique browser request/ajax request
EDIT
2nd Option: I think you have a corrupt cookie PHPSESSID . If you try with a browser that doesn't have any cookies set (for the server that is hosting your files), i bet you see the right session values.
Another way to test is, use the same browser, but just add The only thing I can think of is a corrupt cookie PHPSESSID (the default) or whatever cookie you are using, but just add session_name("myStackOverFlowID"); before session_start(); in both these files. the new session_name is not highly recommended: it is just to test.
EDIT: another option
Do the session_write_close() before regenerating the ID
Thanks
Finally, we know that an Android App is involved!
Check if any part of the App code is storing cookies, etc., in cache
Track time using hrtime(true); (recommended instead of microtime for accuracy) see https://www.php.net/manual/en/function.hrtime.php
If possible, clear out the App data on that android phone and test on a different android phone as well
So, after seeing that session was working correctly on my PC browser, I assumed from there that the issue was perhaps purely with how I set up something in my code for the Android app.
As it turns out, my CookieJar implementation was non-persistent. Using PersistentCookieJar instead, I was able to have cookies persist between my activities on the app.
So for anyone having a similar issue, I would suggest reading through this thread and if nothing works, be sure to check your cookie management implementation for the app.
I have a one page website that uses AJAX to load new php files and update the display.
I start my php session on the main page but when I use ajax to update inner html I need those session variables for the new php file being loaded.
This post is similar to this one: PHP Session Variables Not Preserved . But I checked and my php.ini has session.use_cookies = 1
Main Page PHP:
<?php
session_start();
if(isset($_SESSION['views']))
{$_SESSION['views']=$_SESSION['views']+1;}
else
{$_SESSION['views']=1;}
?>
After User Input I use ajax to call a php file and load a subsection of the page:
<?php
if(isset($_SESSION['views']))
{ echo "Views: " . $_SESSION['views'];}
else
{ echo "Views: NOT SET";}
?>
Can someone please tell me what important step I am missing? Thank you.
Update: After adding session_id() call to both the main and sub pages I see that both pages have the same Session_ID. However it still cannot pull the session variable and if i do assign it a value the two same name session variables stay independent of one another.
Answer to the question that this question created: I found that I had to set a static session_save path in my php.ini file. With most paid webhosting services they just have a default container for sessions but it is affected by load balancing. What a releif.
I think you're missing session_start() on the page that Ajax calls.
You need:
<?php
session_start();
if(isset($_SESSION['views']))
{ echo "Views: " . $_SESSION['views'];}
else
{ echo "Views: NOT SET";}
?>
You need to start session session_start() in the other PHP file also, the one you are calling through AJAX.
I ran into what i thought was the same issue when running PHP 7 on IIS Server 2012 today.
I had added:
if(!isset($_SESSION))
{
session_start();
}
to the start of each AJAX file but kept recieving the following PHP Notice:
PHP Notice: A session had already been started - ignoring session_start()
A bit of searching lead me to this thread which pointed me in the right direction to resolving the issues I encountered. Hopefully the following information will assist others encountering the same issue.
After checking the session.save_path value was set, in my case C:\Windows\Temp, I thought it best to check the folder permissions match those of the user account I was running IIS under.
In my case it turned out that the directory I had nominated for session storage (in php.ini) did not have the same user (security permissions) assigned to it as the one which was running the IIS site.
Interestingly sessions worked fine when not using AJAX requests prior to me adding the new user permissions. However AJAX did not pick up the session until I had corrected the permissions issue. Adding the same user account that IIS is running under immediately resolved this issue.
In the case of using a paid web hosting service the default session save path is automatically set like this:
http://php.net/session.save-path
session.save_path = "/tmp/"
You need to place the static path to your root folder there.
You're trying to use existing session data from your application in an ajax call. To do that, change how you're calling session_start like so:
// With ajax calls
if (session_status()==1) {
session_start();
}
When making ajax calls to php scripts that need existing session data, use session_start after session_status.
http://php.net/session_status
Need to initialize the session before you trying to login through ajax call.
session_start();
Initialize on the top of the page from where you start the login ajax call.
So that the SESSIONID will be created and stored the browser cookie. And sent along with request header during the ajax call, if you do the ajax request to the same domain
For the successive ajax calls browser will use the SESSIONID that created and stored initially in browser cookie, unless we clear the browser cookie or do logout (or set another cookie)
I have a one page website that uses AJAX to load new php files and update the display.
I start my php session on the main page but when I use ajax to update inner html I need those session variables for the new php file being loaded.
This post is similar to this one: PHP Session Variables Not Preserved . But I checked and my php.ini has session.use_cookies = 1
Main Page PHP:
<?php
session_start();
if(isset($_SESSION['views']))
{$_SESSION['views']=$_SESSION['views']+1;}
else
{$_SESSION['views']=1;}
?>
After User Input I use ajax to call a php file and load a subsection of the page:
<?php
if(isset($_SESSION['views']))
{ echo "Views: " . $_SESSION['views'];}
else
{ echo "Views: NOT SET";}
?>
Can someone please tell me what important step I am missing? Thank you.
Update: After adding session_id() call to both the main and sub pages I see that both pages have the same Session_ID. However it still cannot pull the session variable and if i do assign it a value the two same name session variables stay independent of one another.
Answer to the question that this question created: I found that I had to set a static session_save path in my php.ini file. With most paid webhosting services they just have a default container for sessions but it is affected by load balancing. What a releif.
I think you're missing session_start() on the page that Ajax calls.
You need:
<?php
session_start();
if(isset($_SESSION['views']))
{ echo "Views: " . $_SESSION['views'];}
else
{ echo "Views: NOT SET";}
?>
You need to start session session_start() in the other PHP file also, the one you are calling through AJAX.
I ran into what i thought was the same issue when running PHP 7 on IIS Server 2012 today.
I had added:
if(!isset($_SESSION))
{
session_start();
}
to the start of each AJAX file but kept recieving the following PHP Notice:
PHP Notice: A session had already been started - ignoring session_start()
A bit of searching lead me to this thread which pointed me in the right direction to resolving the issues I encountered. Hopefully the following information will assist others encountering the same issue.
After checking the session.save_path value was set, in my case C:\Windows\Temp, I thought it best to check the folder permissions match those of the user account I was running IIS under.
In my case it turned out that the directory I had nominated for session storage (in php.ini) did not have the same user (security permissions) assigned to it as the one which was running the IIS site.
Interestingly sessions worked fine when not using AJAX requests prior to me adding the new user permissions. However AJAX did not pick up the session until I had corrected the permissions issue. Adding the same user account that IIS is running under immediately resolved this issue.
In the case of using a paid web hosting service the default session save path is automatically set like this:
http://php.net/session.save-path
session.save_path = "/tmp/"
You need to place the static path to your root folder there.
You're trying to use existing session data from your application in an ajax call. To do that, change how you're calling session_start like so:
// With ajax calls
if (session_status()==1) {
session_start();
}
When making ajax calls to php scripts that need existing session data, use session_start after session_status.
http://php.net/session_status
Need to initialize the session before you trying to login through ajax call.
session_start();
Initialize on the top of the page from where you start the login ajax call.
So that the SESSIONID will be created and stored the browser cookie. And sent along with request header during the ajax call, if you do the ajax request to the same domain
For the successive ajax calls browser will use the SESSIONID that created and stored initially in browser cookie, unless we clear the browser cookie or do logout (or set another cookie)
Due to server settings I am having to use $_COOKIE instead of $_SESSION to manage session vars for a project.
On my search form I set an initial cookie but am unclear whether this is helpful or needed?
setcookie('NOSG', 'oHai', time()+7200, '/', 'some.org');
Each time the search results page loads I iterate over the cookies and back date the ones I need to clear and then set the new values like so:
if ($board) {
foreach ($_COOKIE as $k => $v) {
if (preg_match('/boa_/', $k)) {
setcookie($k, '', time()-3600, '/', 'some.org');
}
}
foreach ($people as $p) {
setcookie('boa_'.$p->ID, $p->whatever, time()+7200, '/', 'some.org');
}
}
Mostly this is used for making sticky selections in multi-line <SELECT> inputs.
Is this approach sound? I have rarely used $_COOKIE for anything.
// EDIT 1:12 PM GMT-06:00
All of the comments and answers are focused on fixing sessions. I assume this is because there is some reason the method suggested is NOT sound? The question asked is about using $_COOKIE to remember form settings. Would anyone care to respond as to why the method I am using is or is not appropriate to the problem?
The error
Permission denied. session.save_path is set to /var/lib/php/session PHP Warning: Unknown: Failed to write session data (files). Please verify that the current setting of session.save_path is correct (/var/lib/php/session) in Unknown on line 0
Is due to an error on the part of your host/system administrator. They should set the permissions on /var/lib/php/session to 777 so it is writable by all users. If they are using something that executes your PHP script as your user, the data is still safe because your user will own the session data file so no one else can view or modify it.
Alternatively, you can change the session save path on the fly to a directory under your control.
If you were to have a common file that initiated your session, add this before session_start():
session_save_path('/home/yoursite/sessions');
// or
session_save_path($_SERVER['DOCUMENT_ROOT'] . '../sessions');
// or, an alternate method
ini_set('session.save_path', '/home/yoursite/sessions');
session_start();
Then just created that folder and set the permissions appropriately so it is readable/writable by your user only.
Technically all a session is, is a text file (OK, you can hold the data in a database as well) containing variables that's identified by a value held in a cookie (or the address bar).
It wouldn't be impossible to recreate the functionality within PHP using things like setcookie(), serialize() and file_put_contents() writing to a folder outside the web tree ... though you might also need a Cron job to schedule garbage collection (to be fair, PHPs native session GC doesn't seem to be spectacular).
You'd just need to create a custom session handling object and set the "session" id for it in a cookie exactly the same as if you were using normal session handling - except instead of using $_SESSION you'd use you Session::get() and Session::set() methods.
If you keep the API clean then, at a future date if you manage to get session handling enabled on the server, you'd only need to tweak your session handling object and it wouldn't affect the rest of your program code - it's probably a good idea to abstract away then session handling anyway.
None of the respondents addressed my question: Is using $_COOKIE to store session data a sound method?
Experience has taught me what they would not. Not all browsers handle cookies in the same way. For instance Internet Explorer has limits per domain on the number of cookies: http://support.microsoft.com/kb/941495
So the answer is- $_SESSION is superior to cookies as it is handled by PHP in the same manner for all browsers.
I've used session vars multiple times in the past, with no problems, but now it's got me...
The $_SESSION var I am setting is becoming unset every time the PHP script is fired, although it is setting ok for one variable at a time.
if (!isset($_SESSION['badList'])) {
print 'not set - again?';
$_SESSION['badList'][0] = $lineNum;
}
else
{
$_SESSION['badList'][count($_SESSION)] = $lineNum;
}
Here 'not set - again?' fires every time I perform the suitable action, i.e. PHP is not able to find the initial session var. The session cache seems to clear completely when a script is run, which sort of ruins the point of sessions.
What can I do? Many thanks.
Ensure you've called session_start(), /etc/php.ini (or system equivalent) has a session.save_path set (ususally /var/lib/php/session/) and that directory is writable by your web server (on Linux it should be drwxrwx---) and that your disk is not full. If your sessions are being written to a remote store (database, memcached etc) make sure you can connect to that with the credentials your app uses (if applicable).
edit: also ensure you are calling session_write_close() at the end of your request - if you don't then the session data may not be written