0

I was having issues with the session file being locked, so I added session_write_close() once I was done with the session. The script worked properly before that, however, once I leave the sign-in page now, the session is blank.

Session is started at the top of index.php which includes the sign in page:

$result = 'token_valid';
$_SESSION['user'] = $email;
print_r($_SESSION);
session_write_close();
print_r($_SESSION);

The session data is returned properly both times on the sign-in page.

Array ( [user] => abc@gmail.com ) Array ( [user] => abc@gmail.com )

A link returns to the home page, which calls a function to check if logged in...

function user_is_signed_in() {
    print_r($_SESSION);
    session_write_close();

    if($user == '') {
        return False;
    }
    else {
        return True;
    }

}

The session no longer has any data.

Full index.php

<?php 

session_start();

include_once('fnc/database.php');
include_once('fnc/user.php');

if(!user_is_signed_in()) {
  include('sign-in.php');
}
else {
  $url = parse_url($_SERVER['REQUEST_URI']);
  if(!$url['query'])
  {
    include('home.php');
  }
  else {
    if(isset($_GET['media']))
    {
      include($_GET['media'].'.php');
    }
    if(isset($_GET['user']))
    {
      include($_GET['user'].'.php');
    }

  }

}

.

.

Workaround (probably filthy)

Issue seems to be caused by the reading/writing of the actual session file. Used the session_id generated by PHP and just created a secondary session file. Do not save in same folder (or if you do, change the filename) - session_start seems to delete and regenerate the session file PHP manages and you'll lose any data written there.

session_start();
$sess = array();
$sess = $_SESSION;
$sess["id"] = session_id();
//print_r($sess);
session_write_close();

Create session_data in session folder

        $session_details = "user|".$email;

        $session_file = "/Programs/XAMPP/tmp/session_data/sess_".$sess["id"];
        //echo $session_details;

        $fh = fopen($session_file, 'w+');
        fwrite($fh, $session_details);
        fclose($fh);

Read session data from this file instead of the session

    $session_path = "/Programs/XAMPP/tmp/session_data/sess_".$sess["id"];
    $fh = fopen($session_path, 'r');
    $session_file = fread($fh, filesize($session_path));

    $exploded_session = explode("\n", $session_file);

    $session_data = array();

    foreach($exploded_session as $line)
    {
        $tmp = explode("|", $line);
        $session_data[$tmp[0]] = $tmp[1];
    }

    return $session_data["user"];

    fclose($fh);
Ash
  • 1
  • 3
  • Are you *starting* the session again on that other page…? – deceze Oct 20 '19 at 07:31
  • Also, `$user` is not defined; is that an error in posting here, or your actual problem? – deceze Oct 20 '19 at 07:32
  • What deceze said, and also did u mean to reference $SESSION[‘user’] as opposed to $user in the function? – DanielRead Oct 20 '19 at 07:33
  • Index.php includes both pages. I've added that for clarification. $user not being defined is irrelevant? Just bad code left from messing around. print_r($_SESSION) above that does not return any data. – Ash Oct 20 '19 at 07:42
  • Do you have SSH access to the server? – patrick3853 Oct 20 '19 at 07:50
  • Also, see this comment on the `session_write_close` manual: https://www.php.net/manual/en/function.session-write-close.php#63970 – patrick3853 Oct 20 '19 at 07:52
  • It is a local XAMPP server – Ash Oct 20 '19 at 07:56
  • Check the session directory on the server (you can use `session_save_path()` to find the directory) _after_ the login page writes the session, but _before_ redirecting to the login page. Do this by putting a die() statement after calling `session_write_close` but before the redirect. Then find the latest session file and see if the data was written to it. It sounds like the session data is not getting saved to the file for some reason. – patrick3853 Oct 20 '19 at 08:01
  • Also, you can echo `session_id()` to see the current session ID, and the session file should be named the same. If the data is being written to the file, make sure it is using the same session ID after the redirect. You can use `file_put_contents` to write the session ID before and after the redirect to a random file, then check that file and see if they are the same. – patrick3853 Oct 20 '19 at 08:07
  • The session ID remains the same. I cleared /tmp where the sessions are stored and only one file is created. However, the file is empty, so there seems to be something to this... – Ash Oct 20 '19 at 08:10
  • Okay, this is good you're making progress. The session file does exist and persists between page loads. Since the file is created, it seems that file permissions are not the issue (i.e. PHP is able to write to the directory). Just for debugging, remove the `session_write_close` and see if the data is written to the file. If so, that will let you know there is something wrong with `session_write_close`, which is very likely given you are using XAMPP, which is known to have some funny quirks to it. – patrick3853 Oct 20 '19 at 08:12
  • A couple of more debugging tips. Check the value of `session.gc_maxlifetime` and make sure it's not set to something like 0 (I'd set to 3600 for testing). Also, make sure `display_errors` is set to `-1` so you are seeing any errors that may occur (and as always, check your error log on the server) – patrick3853 Oct 20 '19 at 08:18
  • Yes, removing session_write_close does resolve the issue and the script works again. (Which was expected, it worked before adding). Is there a better option for a local server on Windows? Error log does not have anything interesting to say – Ash Oct 20 '19 at 08:20
  • Let's try one more thing. Add `sleep(1)` right before you call `session_write_close()`, and then see if the data is written to the session file. – patrick3853 Oct 20 '19 at 08:27
  • Also, try adding `session.auto_start = On` in your `php.ini` – patrick3853 Oct 20 '19 at 08:42
  • Added a 30s sleep to no avail. Session auto start has no effect. – Ash Oct 20 '19 at 08:43
  • Did you check out the comment on the PHP manual for `session_write_close` I linked to earlier? Also, I just came across this on SO, I think we've tried most of these already, but you should run through them and see: https://stackoverflow.com/questions/19644624/setting-session-doesnt-work-on-localhost-using-xampp – patrick3853 Oct 20 '19 at 08:46
  • I did. As its not redirecting automatically (just prints a link), I don't think that's the case either. I don't see anything on that SO link that we haven't tried. – Ash Oct 20 '19 at 08:49
  • So you tried adding `$_SESSION['email'] = null` right after calling `session_start()`? If so, I'm pretty much out of ideas at this point. Session issues can be tricky, and this sounds more like a quirk with XAMPP on Windows. I don't know an alternative to `session_write_close` to solve your file locking problems, but I think your best bet is to try to figure out why that's happening in the first place so you don't need to use `session_write_close`. fwiw, I've never had an issue with the session files being locked. Worst case, you can store sessions in the DB but that's a lot more work. – patrick3853 Oct 20 '19 at 08:53
  • I just came across this one too, so make sure you have tried setting `session_auto_start = On` and that the config change was picked up (you might need to restart XAMPP, you can verify with `phpinfo()`) https://stackoverflow.com/a/44957966/8001997 – patrick3853 Oct 20 '19 at 08:57
  • $_SESSION['email'] = null does set correctly at the beginning, but then doesn't update. Session.auto_start is on as well. I'm using PHP to mirror a large file if required to S3, and I'd like the user to be able to let it do its business and continue using the site. Without closing the session the user cannot do anything but sit on the page. I guess I may have to look into alternate ways to handle the session. – Ash Oct 20 '19 at 09:07

0 Answers0