Unter PHP "leben" Sessions standardmaessig 24 Minuten, das heisst wenn ein User 24 Minute inaktiv war wird er zum Ziel des Garbage Collectors.
Dieser wird, je nach Einstellung, bei einem gewissen Prozentsatz an session_start()-Aufrufen ausgefuehrt.
Das hab ich mir zu nutze gemacht und ueberpruefe ob das Session-File noch vorhanden ist, wenn nicht wird der entsprechende Eintrag aus der DB geloescht.
Es gibt also fuer jedes Session-File einen DB-Eintrag, nicht mehr, nicht weniger.
Da ich natuerlich bei meinem Anbieter nicht auf das Verzeichnis zugreifen darf in dem die Sessions standardmaessig gespeichert werden musste ich das per session_save_path() in ein eigenes Verzeichnis verlegen. Das Problem hierbei ist jedoch, dass da der Garbage Collector nicht durchgeht.
Ich musste nun also meine eigene Garbage Collection schreiben, welche ich dann mit einer Zeit von nur 10 Minuten ausgestattet hab, statt der standardmaessigen 24 Minuten.
Der Code ist ein wenig komplexer, da er mit im Cookie-Check drinhaengt. Der ist dafuer da um festzustellen ob der User Cookies deaktiviert hat und dies soll mit der Session in der DB gespeichert werden um das Login mit und ohne Cookies zu ermoeglichen.
Hier mal die Scripts:
Uebrigens, die sessioncheck.php wird in meiner index.php includet, das sieht da so aus:
PHP:
$sessioncheckcaller="index.php";
include("sessioncheck.php");
sessionpath.php
PHP:
<?
$session_path="../tmp";
session_save_path($session_path);
?>
sessioncheck.php
PHP:
<?
include("sessionpath.php");
include("cleansessions.php");
if ($_GET["sessionid"])
{
$sessionid=$_GET["sessionid"];
session_id($sessionid);
}
session_start();
if (!$sessionid)
{
$sessionid=session_id();
}
$sessions=mysql_query("select * from sessions where sessionid='$sessionid'",$db);
$session=mysql_fetch_array($sessions);
if (!$session)
{
header("Location:cookiecheck.php?caller=".$sessioncheckcaller."&sessionid=".$sessionid);
}
$sessionname=session_name();
if ((($session[2]=="0") && ($_COOKIE[$sessionname])) || (($session[2]=="1") && (!$_COOKIE[$sessionname])))
{
session_regenerate_id();
session_destroy();
header("Location:".$sessioncheckcaller);
}
if ($session[2]=="1")
{
$sessionparm="";
$sessionparm_link="";
$sessionparm_header="";
}
else
{
$sessionparm="?sessionid=".$sessionid;
$sessionparm_link="&sessionid=".$sessionid;
$sessionparm_header="&sessionid=".$sessionid;
}
?>
cleansessions.php
PHP:
<?
$session_prefix="sess_";
$sessions=mysql_query("select * from sessions",$db);
while ($session=mysql_fetch_row($sessions))
{
if (file_exists($session_path."/".$session_prefix.$session[0]))
{
if (filemtime($session_path."/".$session_prefix.$session[0])+600<time())
{
unlink($session_path."/".$session_prefix.$session[0]);
}
}
if (!file_exists($session_path."/".$session_prefix.$session[0]))
{
mysql_query("delete from sessions where sessionid='$session[0]'",$db);
}
}
?>
cookiecheck.php
PHP:
<?
if (($_GET["sessionid"]) && ($_GET["caller"]))
{
$sessionid=$_GET["sessionid"];
$caller=$_GET["caller"];
include("sessionpath.php");
session_id($sessionid);
session_start();
if (!$_GET["check"])
{
setcookie("test","test",time()+3600);
header("Location:cookiecheck.php?sessionid=".$sessionid."&check=1&caller=".$caller);
}
else
{
if ($_COOKIE["test"]=="test")
{
$cookies="1";
}
else
{
$cookies="0";
}
include("connectdb.php");
mysql_select_db("database",$db);
mysql_query("insert into sessions (sessionid,cookies) values ('$sessionid','$cookies')",$db);
$db=mysql_close($db);
setcookie("test","test",time()-3600);
if ($cookies=="1")
{
header("Location:".$caller);
}
else
{
header("Location:".$caller."?sessionid=".$sessionid);
}
}
}
?>