session_status() returns none on reload - php

I have already seen this identical opposite question and its OP code sample seems perfectly fine to me. I've also read (including PHP docs) that session can be checked with session_status() on PHP >= 5.4 and it should be fine to do so before calling session_start() to determine if it already exists.
Now, I'm using PHP 5.4.16 on a CentOS 7.10 machine and the session_status() always returns 1 (PHP_SESSION_NONE) for me, only when I reload the page with this example:
<?php
$status = session_status();
session_start();
echo "The session status is : $status";
I expect it returns PHP_SESSION_ACTIVE (2) when I reload page (and I'm not forcing-reload with cache clear). I'm using latest Chrome version, and the page is embedded inside a virtual host with HTTPS over port 8443.
I've checked the PHP version with both php --version and via phpinfo() script to discard any version conflict just in case, and they're same. Additionally, when I visit the session script page, the server creates empty files at /var/lib/php/session directory. I didn't change default PHP settings for session or anything.
To make it clear: the session_status() works fine if checked afterwards on same script execution (The session status is : 2), but naturally I'm not interested in that since I want to check if session exist in first place.
What could be wrong?

Your session_status will always be PHP_SESSION_NONE until you call session_start in the lifetime of the current request. It does not matter if on some previous request you "already started" a session: you need to "re-start" it, to resume a previously started session. This is done via cookies.
If your intent is to start a session only if the user already did something in the past that started a session (eg. they already logged in previously) and you want to resume a session but not start a new one, then you could simply check if (isset($_COOKIE['PHPSESSID'])).
This may be beneficial if you know most of your users won't need a session, and you want to avoid cookies and the overhead involved with a session, but still be able to handle the cases when a session is needed.

In my experience, session_status() only allow you to know if a session has been started, so if session_start() has been called in the current script.
PHP_SESSION_DISABLED I think that this is returned if session are disabled in PHP configuration.
PHP_SESSION_NONE is returned if the session has not been started in the current script
PHP_SESSION_ACTIVE if a session has been started in the current script.
This post might interrest you https://stackoverflow.com/questions/32356373/how-to-disable-session-in-php#:~:text=You%20can%20disable%20the%20session,ini%20.
A way to check if a session has been started in a different script would be
<?php
session_start();
if (!isset($_SESSION['init'])) {
echo 'first time session';
$_SESSION['init'] = true;
}

Related

PHP session resetting

I have PHP 5.6 running on IIS 8.5. I used this test log:
echo '<p>'.sizeof($_SESSION).' - '.session_id().' - '.ini_get('session.cookie_domain').'</p>';
With it I see that $_SESSION has some elements, cookie_domain is properly set in php.ini as my domain, but session_id() has a different string on each page load. session_start() is being called on every page load.
Any idea on what I can do to make session persistent?
$sessionfile = ini_get('session.save_path') . '/' . 'sess_'.session_id(); shows where the session file is. I'm able to open it and data is there. Indeed it's something in the creation of each session, not in saving their files.
Is it possible that some IIS setting or some asp is reseting the session?
This problem occur most times if you don't have permissions to store the session in your IIS. I had the same problem before a long time. To correct the permissions or the session path solved my problem.

PHP session not being unset on new server

I recently moved to a new DigitalOcean VPS server, and I'm running Ubuntu 14.04 and Apache. This is the first time I set up my own server. I imported my website into the new server. Everything seems to be working but the logout script where I basically unset and destroy the session. For some reason, this doesn't seem to be working anymore.
Here's the code for my logout script
<?PHP
session_start();
session_unset();
session_write_close();
session_destroy();
session_start();
$_SESSION = array();
$_SESSION['logged_out'] = 1;
header ("Location:index.php");
?>
When the page is redirected, the user is still logged in and the session cookie is still set.
I remember having the same problem as you.
Try to delete your SESSION using : unset($_SESSION['session_you_need_to_destroy']);
I guess if you destroy only one session, you member will be log off.
Hope it's work for you :)
Just for anyone else's future reference, I solved the problem. The URL for the login script was http://website.com (without the www) and the rest of my site used http://www.website.com (with the www).

Can't write PHP cookies or sessions on RackSpace server

I'm working on a RackSpace server, and I am unable to successfully write cookies or persistent sessions through PHP (I can write javascript cookies just fine).
The cookies are never written at all, and the sessions are never accessible on any page but the one they're written on. I've tried the exact same code on a different server, and it worked just fine -- so I'm assuming it's some kind of configuration issue.
Here's an example:
Sessions
Page 1:
session_start();
$_SESSION['mysession'] = 'hello';
//writes correct value
echo $_SESSION['mysession'];
Page 2:
session_start();
//this dumps 'NULL'
var_dump($_SESSION['mysession']);
Cookies:
//this never gets written.
setcookie($mycookie, $myvalue, time() + (86400 * 30), "/");
Are there any particular server settings I should be looking at?
I ran phpinfo, and see my session.save_path. I tried setting that to 777 just to see if it would help, but it did not.
I'm stumped, and their support couldn't help me. Anyone have any ideas?
Edit:
Upon closer inspection, I can see that the sessions are being written -- I just can't read them.
You can gather more information by creating a php file with content:
<?php phpinfo();
Request this site and search for the session settings.
- Are sessions really enabled?
- Which session save handler is used?
Maybe the session data is not even saved in a file and the error is anywhere else.

How does PHP detect that a session has timed out?

I'm wondering how PHP detects that a specific session has timed out.
In detail: I'm using the default (file based) session handler, with a default session lifetime and so on. Everything in php.ini is on default.
If now a session is started, PHP does a check (depending non session.gc_divisor and session.gc_probability) if there are any timed out sessions. But from where does get PHP the last session access time from the sessions to check against?
The session file itself contains only the workload, e.g. x|i:1; for a $_SESSION['x'] = 1;, so there is no information about the last session access time.
I think that there are no in-memory information related to session start times as the sessions are still working after a full server restart.
So, where does PHP get the information from? Is it comparing the mtime/ctime of the session file?
PHP's default session handler stores the $_SESSION data in a file using serialize(), in the directory specified by session.save_path. Generally the filename looks something like $filename = 'sess_' . session_id().
Since it's just a file, PHP can use the file's mtime (time of last modification) to determine which session files are stale. Basically it'll grab all the session files whose mtime exceeds the session.gc_maxlifetime value and unlink() them. As you've said, the probability of the cleanup occuring is governed by the session.gc_* ini variables.
Now, if you create your own session handlers with session_set_save_handler(), this is all out the window, and you've now got control over how sessions are stored and cleaned up, but this does explain the default behavior.

session_start hangs

since a few hours our server hangs every time you do a session_start.
For testing purposes i created a script which looks like this:
<?php
session_start();
?>
Calling it from the console hangs and it can't even be stopped with ctrl-c, only kill -9 works. The same for calling it via Apache. /var/lib/php/session/ stays empty but permissions are absolutely fine, www can write and also has read permissions for all parent folders.
According to the admins there were no changes made on the server and there is no special code registered for sessions. The Server is CentOS 4 or 5 and yesterday everything was working perfectly. We rebooted the server and updated PHP, but nothing changed.
I've ran out of ideas, any suggestions?
UPDATE
We solved this problem by moving the project to another server, so while the problem still exists on one server there is no immediate need for a solution anymore.
I will keep the question open in case someone has an idea for others having a similar problem in the future, though.
There are many reasons for that, here are a few of them:
A. The session file could be opened exclusively.
When the file lock is not released properly for whatever reason, it is causing session_start() to hang infinitely on any future script executions.
Workaround: use session_set_save_handler() and make sure the write function uses fopen($file, 'w') instead of fopen($file, 'x')
B. Never use the following in your php.ini file (entropie file to "/dev/random"), this will cause your session_start() to hang:
<?php
ini_set("session.entropy_file", "/dev/random");
ini_set("session.entropy_length", "512");
?>
C.
session_start() needs a directory to write to.
You can get Apache plus PHP running in a normal user account. Apache will then of course have to listen to an other port than 80 (for instance, 8080).
Be sure to do the following things:
- create a temporary directory PREFIX/tmp
- put php.ini in PREFIX/lib
- edit php.ini and set session.save_path to the directory you just created
Otherwise, your scripts will seem to 'hang' on session_start().
If this helps:
In my scenario, session_start() was hanging at the same time I was using the XDebug debugger within PHPStorm, the IDE, on Windows. I found that there was a clear cause: Whenever I killed the debug session from within PHPStorm, the next time I tried to run a debug session, session_start() would hang.
The solution, if this is your scenario, is to make sure to restart Apache every time you kill an XDebug session within your IDE.
I had a weird issue with this myself.
I am using CentOS 5.5x64, PHP 5.2.10-1. A clean ANSI file in the root with nothing other than session_start() was hanging. The session was being written to disk and no errors were being thrown. It just hung.
I tried everything suggested by Thariama, and checked PHP compile settings etc.
My Fix:
yum reinstall php; /etc/init.d/httpd restart
Hope this helps someone.
To everyone complaining about the 30 seconds of downtime being unacceptable, this was an inexplicable issue on a brand new, clean OS install, NOT a running production machine. This solution should NOT be used in a production environment.
Ok I face the same problem on 2 PC, 1 is MAC mini XAMPP, 1 is Windows 10 Xampp.
Both is php spent infinity to run session_start(). Both PHP version is 7.x.x
I found that session files is lock to read and write. So that I added code to make PHP read session files and immediately unlock when done with
<?php
session_start([
'read_and_close' => true,
]);
?>
or
<?php
//For PHP 5.x
session_start();
session_write_close();
?>
After this PHP unlock session file => Problems solve
The problem: -
Iv experienced (and fixed) the problem where file based sessions hang the request, and database based sessions get out of sync by storing out of date session data (like storing each session save in the wrong order).
This is caused by any subsequent request that loads a session (simultaneous requests), like ajax, video embed where the video file is delivered via php script, dynamic resource file (like script or css) delivered via php script, etc.
In file based sessions file locking prevents session writing thus causing a deadlock between the simultaneous request threads.
In database based session the last request thread to complete becomes the most recent save, so for example a video delivery script will complete long after the page request and overwrite the since updated session with old session data.
The fix: -
If your ajax or resource delivery script doesnt need to use sessions then easiest to just remove session usage from it.
Otherwise you'd best make yourself a coffee and do the following: -
Write or employ a session handler (if not already doing so) as per http://www.php.net//manual/en/class.sessionhandler.php (many other examples available via google search).
In your session handler function write() prepend the code ...
// processes may declare their session as read only ...
if(!empty($_SESSION['no_session_write'])) {
unset($_SESSION['no_session_write']);
return true;
}
In your ajax or resource delivery php script add the code (after the session is started) ...
$_SESSION['no_session_write'] = true;
I realise this seems like a lot of stuffing around for what should be a tiny fix, but unfortunately if you need to have simultaneous requests each loading a session then it is required.
NOTE if your ajax or resource delivery script does actually need to write/save data, then you need to do it somewhere other than in the session, like database.
Just put session_write_close(); befor Session_start();
as below:
<?php
session_write_close();
session_start();
.....
?>
I don't know why, but changing this value in /etc/php/7.4/apache2/php.ini worked for me:
;session.save_path = "/var/lib/php/sessions"
session.save_path = "/tmp"
To throw another answer into the mix for those going bananas, I had a session_start() dying only in particular cases and scripts. The reason my session was dying was ultimately because I was storing a lot of data in them after a particularly intensive script, and ultimately the call to session_start() was exhausting the 'memory_limit' setting in php.ini.
After increasing 'memory_limit', those session_start() calls no longer killed my script.
For me, the problem seemed to originate from SeLinux. The needed command was chcon -R -t httpd_sys_content_t [www directory] to give access to the right directory.
See https://askubuntu.com/questions/451922/apache-access-denied-because-search-permissions-are-missing
If you use pgAdmin 4 this can happen as well.
If you have File > Preferences > SQL Editor > Options > "Auto Commit" disabled, and you just ran a query using the query tool but didn't manually commit, then session_start() will freeze.
Enable auto commit, or manually commit, or just close pgAdmin, and it will no longer freeze.
In my case it seems like it was the NFS Share that was locking the session , after restarting the NFS server and only enabled 1 node of web clients the sessions worked normally .
Yet another few cents that might help someone. In my case I was storing in $_SESSION complex data with several different class objects in them and session_start() couldn't handle the whole unserialization as not every class was loaded on session_start. The solution is my case was to serialize/jsonify data before saving it into the $_SESSION and reversing the process after I got the data out of session.

Categories