forked from bretticus/db-sessions
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsession_handler_memcached.php
More file actions
132 lines (120 loc) · 3.97 KB
/
session_handler_memcached.php
File metadata and controls
132 lines (120 loc) · 3.97 KB
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
<?php
/**
* Database Session Hander
*
* @author Brett Millett <bmillett@olwm.com>
* @version 1.0
*
* @property boolean $available If memcached passed is legit.
* @property Memcached $memcached Instance of memcached.
*/
class SessionHandlerMemcached extends PDOSessionHandler {
protected $available = FALSE;
protected $memcached = NULL;
/**
*
* @param PDO $db
* @param string $key
*/
public function __construct(PDO $db, $memcached) {
if ($memcached instanceof Memcached) {
// attempt to see if memcached is available
$servers = @$memcached->getServerList();
$this->available = is_array($servers);
if ($this->available && !count($servers)) {
$this->available = $memcached->addServer($_SERVER['SERVER_ADDR'], '11211');
}
// set property to instance
$this->memcached = & $memcached;
}
parent::__construct($db);
}
/**
*
* @param string $session_id
* @return boolean
*/
public function destroy($session_id) {
$result = parent::destroy($session_id);
if ($this->available && $result) {
try {
// add result to memory for next time.
$this->memcached->delete($session_id);
} catch (MemcachedException $e) {
$this->email_admins($e->getMessage());
} catch (Exception $e) {
$this->email_admins($e->getMessage());
}
}
return $result;
}
/**
* Get cached value from memory first.
*
* @param string $session_id
* @return string
*/
public function read($session_id) {
if ($this->available) {
try {
$cached = $this->memcached->get($session_id);
if ($cached === FALSE) {
$cached = parent::read($session_id);
// add result to memory for next time.
$this->memcached->add($session_id, $cached, $this->ttl($session_id));
}
} catch (MemcachedException $e) {
$this->email_admins($e->getMessage());
// fallback to parent if memcached exception.
$cached = parent::read($session_id);
} catch (Exception $e) {
$this->email_admins($e->getMessage());
// fallback to parent if any exception.
$cached = parent::read($session_id);
}
} else {
// fallback to parent if no memcached availability.
$cached = parent::read($session_id);
}
return $cached;
}
/**
*
* @param string $session_id
* @param string $session_data
* @return boolean
*/
public function write($session_id, $session_data) {
// always write to database first so we have concurrency among servers.
$result = parent::write($session_id, $session_data);
if ($this->available && $result) {
try {
// add result to memory for next time.
$this->memcached->add($session_id, $cached, $this->ttl($session_id));
} catch (MemcachedException $e) {
$this->email_admins($e->getMessage());
} catch (Exception $e) {
$this->email_admins($e->getMessage());
}
}
return $result;
}
/**
*
* @param string $session_id
* @return mixed NULL if timestamp record is not returned.
*/
protected function ttl($session_id) {
try {
$stmt = $this->prepare('SELECT `timestamp` FROM `%s` WHERE id = ?');
$stmt->execute(array($session_id));
$result = $stmt->fetch(PDO::FETCH_OBJ);
if (!empty($result)) {
return time() - $result->timestamp;
}
} catch (PDOException $e) {
$this->email_admins($e->getMessage());
}
return NULL;
}
}