Session Class
In de database worden de sessie's opgeslagen. Zoals je aan de clean_session() functie ziet, worden oude sessies gedeleted. Echter wanneer ik na 15sec de pagina refresh, staat de sessie nog altijd in de DB. Op een of andere manier wordt de sessie wel gewijzigd, maar direct daarna weer aangemaakt met de zelfde data. Dat eerste kan ik nog verklaren, maar het tweede niet? Wie weet wat hier aan te doen is, volgens mij zie ik gewoon iets over het hoofd.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?php
class session {
private $instance;
function __construct() {
session_set_save_handler(
array($this, "open_session" ),
array($this, "close_session" ),
array($this, "read_session" ),
array($this, "write_session"),
array($this, "destroy_session"),
array($this, "clean_session" )
);
}
function open_session() {
require_once('mysql.class.php');
if ($this->instance = mysql::get_instance()->connection) {
return true;
}
}
function close_session() {
return mysql_close($this->instance);
}
function read_session($sid) {
$query = sprintf('SELECT data FROM sessions WHERE id="%s"',mysql_real_escape_string($sid));
$result = mysql_query($query);
if (mysql_num_rows($result) == 1) {
list($data) = mysql_fetch_array($result);
return $data;
}
else {
return '';
}
}
function write_session($sid, $data) {
$query = sprintf('REPLACE INTO sessions (id, data, last_accessed) VALUES ("%s", "%s", NOW())',mysql_real_escape_string($sid), mysql_real_escape_string($data));
$result = mysql_query($query);
return mysql_affected_rows($this->instance);
}
function destroy_session($sid) {
$query = sprintf('DELETE FROM sessions WHERE id="%s"',mysql_real_escape_string($sid));
$result = mysql_query($query);
$_SESSION = array();
return mysql_affected_rows($this->instance);
}
function clean_session($expire) {
$query = sprintf('DELETE FROM sessions WHERE DATE_ADD(last_accessed, INTERVAL %d SECOND) < NOW()', (int) $expire);
$result = mysql_query($query);
return mysql_affected_rows($this->instance);
}
function __destruct() {
session_write_close();
$this->instance = null;
}
}
//ini-settings
ini_set('session.gc_maxlifetime','15');
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 1);
$session = new session();
session_start();
?>
class session {
private $instance;
function __construct() {
session_set_save_handler(
array($this, "open_session" ),
array($this, "close_session" ),
array($this, "read_session" ),
array($this, "write_session"),
array($this, "destroy_session"),
array($this, "clean_session" )
);
}
function open_session() {
require_once('mysql.class.php');
if ($this->instance = mysql::get_instance()->connection) {
return true;
}
}
function close_session() {
return mysql_close($this->instance);
}
function read_session($sid) {
$query = sprintf('SELECT data FROM sessions WHERE id="%s"',mysql_real_escape_string($sid));
$result = mysql_query($query);
if (mysql_num_rows($result) == 1) {
list($data) = mysql_fetch_array($result);
return $data;
}
else {
return '';
}
}
function write_session($sid, $data) {
$query = sprintf('REPLACE INTO sessions (id, data, last_accessed) VALUES ("%s", "%s", NOW())',mysql_real_escape_string($sid), mysql_real_escape_string($data));
$result = mysql_query($query);
return mysql_affected_rows($this->instance);
}
function destroy_session($sid) {
$query = sprintf('DELETE FROM sessions WHERE id="%s"',mysql_real_escape_string($sid));
$result = mysql_query($query);
$_SESSION = array();
return mysql_affected_rows($this->instance);
}
function clean_session($expire) {
$query = sprintf('DELETE FROM sessions WHERE DATE_ADD(last_accessed, INTERVAL %d SECOND) < NOW()', (int) $expire);
$result = mysql_query($query);
return mysql_affected_rows($this->instance);
}
function __destruct() {
session_write_close();
$this->instance = null;
}
}
//ini-settings
ini_set('session.gc_maxlifetime','15');
ini_set('session.gc_probability', 1);
ini_set('session.gc_divisor', 1);
$session = new session();
session_start();
?>
Jij laadt pagina
-> session_start
-> session_close
-> INSERT
-> clean (maar niet die vorige insert, die is nog geen 15 sec oud)
Jij herlaadt de pagina
-> session_start
-> session_close
-> REPLACE
-> clean (de oude is nu met een nieuwe datum, dus ook dit maal wordt hij niet weggedaan)
Je zou het kunnen testen door een tweede browser erbij te pakken, en die ook de pagina te laten laden. Aangezien de twee browsers niet hun cookies, en dus hun sessies delen, zou je twee sessies moeten zien hierna. Na 15 seconden herlaadt je de pagina in één van de twee browsers. Hierna zou dan nog maar 1 sessie in de database aanwezig moeten zijn.
Gewijzigd op 01/01/1970 01:00:00 door Jelmer -
Ik snap eigenlijk nog steeds niet waar nu de fout zit. Ik heb echo's in de session_write en de session_clean functies gezet om te kijken wanneer ze uitgevoerd worden.
Dit is de volgorde:
eerst clean en dan write
Ik zou denken dus, dat tijdens de clean de sessie uit de DB gegooid wordt (wat ook werkelijk gebeurd want mysql_affected_rows geeft 1 terug). En dan komt die write, en op een of andere manier schrijft hij de sessie opnieuw in de DB inc. alle data. Hoe kan ik dit nu oplossen?
Update:
Ok, ik heb een soort work around gevonden:
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?php
function clean_session($expire) {
$query = sprintf('DELETE FROM sessions WHERE DATE_ADD(last_accessed, INTERVAL %d SECOND) < NOW()', (int) $expire);
$result = mysql_query($query);
if (mysql_affected_rows($this->instance)) {
session_destroy();
return true;
}
}
?>
function clean_session($expire) {
$query = sprintf('DELETE FROM sessions WHERE DATE_ADD(last_accessed, INTERVAL %d SECOND) < NOW()', (int) $expire);
$result = mysql_query($query);
if (mysql_affected_rows($this->instance)) {
session_destroy();
return true;
}
}
?>
Maar volgens mij houdt dit dus in dat als er een record gevonden wordt wat ouder is dan $expire dan wordt de huidige sessie beeindigd. Dit is dus nog steeds niet goed want, er zijn straks meerdere sessies in die DB, dus 1 verlopen sessie, moet niet inhouden dat ze allemaal verlopen :(
Niemand die ooit een gelijke classe heeft gemaakt of gezien??
Gewijzigd op 01/01/1970 01:00:00 door Jaws
*bump* niemand?