I have found the solution for my setup: Apache/PHP on an Ubuntu 20.04 box. Details of the machine are further below.
Pre-requisites:
- On a new connection to your server
$_SERVER['HTTP_COOKIE']
is not set. This solution relies fully on that fact. More research is needed to ascertain this always works the same on every installation. Your box may behave differently, so check it!
- Once the session is created, write a known variable to the session. It is always wise to do so, to make sure the session file's last modified timestamp is reset each time the script is called. This prevents the garbage collector from removing the session file prematurely.
To do:
- Create a php file like the one below and include/require that file on every PHP request to your server.
- Once required/included: examine
$_SESSION['state']
and act accordingly
Script:
<?php
# To eventually use it, remove all output commands like print_r, echo, print, etc.
# For testing purposes this is OK.
# Helpful to know, you may uncomment:
# echo 'maxlifetime : ' . ini_get('session.gc_maxlifetime') . ' seconds.' . PHP_EOL;
# echo 'save_path : ' . ini_get('session.save_path') . PHP_EOL;
# Serves output in fixed font. Uncomment/remove as you see fit
# echo '<pre>';
# Start a NEW session or load an EXISTING one
if (!session_id()) {
session_start();
}
# If the session is a new one, variable $_SESSION['moment'] is not yet set
if (!isset($_SESSION['moment'])) {
# The variable was not set, check if $_SERVER['HTTP_COOKIE'] was set or not
if (!isset($_SERVER['HTTP_COOKIE'])) {
echo 'New connection ('.session_id().'), empty session.' . PHP_EOL . 'Session state: NEW.' . PHP_EOL;
$_SESSION['state'] = 'NEW';
}
else {
echo 'Existing connection ('.session_id().'), but empty session.' . PHP_EOL . 'Session state: EXPIRED.' . PHP_EOL;
$_SESSION['state'] = 'EXPIRED';
}
}
# The variable was set, the session file was succesfully read this is a continued session
else {
echo 'Existing connection ('.session_id().'), but variable $_SESSION[moment] exists: ' . $_SESSION['moment'] . '.' . PHP_EOL . 'Session state: CONTINUED.' . PHP_EOL;
$_SESSION['state'] = 'CONTINUED';
}
# Always write something to the session file to change the last modified timestamp
$_SESSION['moment'] = Date("Y-m-d H:i:s");
?>
Output on a new connection:
New connection (qvgo4lfd9cibrqbmgngmp1gto1), empty session.
Session state: NEW.
Output on a refresh from the browser:
Existing connection (qvgo4lfd9cibrqbmgngmp1gto1), but variable $_SESSION[moment] exists: 2020-09-11 15:16:10.
Session state: CONTINUED.
Output after session has gone:
Existing connection (qvgo4lfd9cibrqbmgngmp1gto1), but empty session.
Session state: EXPIRED.
I also uploaded the script to my production box (Ubuntu 18.04). Identical results.
Checked on Windows 10:
- Internet Explorer 11.1082.18362.0
- Chrome 85.0.4183.102
- Firefox 67.0
- Edge 85.0.564.51
- Avast 85.0.5675.84
Checked on MacOS Catalina (85.0.5675.84)
- Chrome 85.0.4183.102
- Safari 13.1.2 (15609.3.5.1.3)
About the servers:
Apache
Server version: Apache/2.4.41 (Ubuntu)
Server built: 2020-08-12T19:46:17
PHP
PHP 7.4.3 (cli) (built: May 26 2020 12:24:22) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.3, Copyright (c), by Zend Technologies
Ubuntu
Distributor ID: Ubuntu
Description: Ubuntu 20.04.1 LTS
Release: 20.04
Codename: focal