1: <?php
2: 3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13: 14: 15: 16: 17: 18: 19: 20: 21:
22:
23: class Session_DbStorage extends Session_Session
24: {
25: 26: 27:
28: private $dbh;
29:
30:
31: private $options;
32:
33:
34: private $ttl;
35:
36: static private $instance;
37:
38: private function __construct($dbh,$opts,$ttl)
39: {
40: $this->dbh = $dbh;
41: $this->ttl = $ttl;
42: $this->options = array_merge(array(
43: 'db_table' => 'php_session',
44: 'db_id_col' => 'sess_id',
45: 'db_data_col' => 'sess_data',
46: 'db_time_col' => 'sess_time'
47: ), $opts);
48:
49:
50: session_set_save_handler(
51: array($this, 'sessionOpen'),
52: array($this, 'sessionClose'),
53: array($this, 'sessionRead'),
54: array($this, 'sessionWrite'),
55: array($this, 'sessionDestroy'),
56: array($this, 'sessionGC')
57: );
58: }
59:
60: 61: 62: 63: 64: 65: 66:
67: public static function getInstance($dbh,array $opts,$ttl=null)
68: {
69: if(!isset(self::$instance))
70: self::$instance = new Session_DbStorage($dbh,$opts,$ttl);
71:
72: return self::$instance;
73: }
74:
75: public function sessionClose()
76: {
77: return true;
78: }
79:
80: public function sessionOpen($path = null,$name = null)
81: {
82:
83: }
84:
85: public function sessionDestroy($id)
86: {
87: $db_table = $this->options['db_table'];
88: $db_id_col = $this->options['db_id_col'];
89:
90: $sql = 'DELETE FROM '.$db_table.' WHERE '.$db_id_col.'= ?';
91:
92: try
93: {
94: $stmt = $this->dbh->prepare($sql);
95: $stmt->bindParam(1, $id, PDO::PARAM_STR);
96: $stmt->execute();
97: }
98: catch (PDOException $e)
99: {
100: throw new Exception(sprintf('Unable to destroy the session. Message: %s', $e->getMessage()));
101: }
102:
103: return true;
104: }
105:
106: public function sessionGC($lifetime)
107: {
108: $db_table = $this->options['db_table'];
109: $db_time_col = $this->options['db_time_col'];
110:
111:
112: $sql = 'DELETE FROM '.$db_table.' WHERE '.$db_time_col.' < \''.date("Y-m-d H:i:s").'\'';
113:
114: try
115: {
116: $this->dbh->query($sql);
117: }
118: catch (PDOException $e)
119: {
120: throw new Util_ExceptionHandler(sprintf('Unable to clean expired sessions. Message: %s', $e->getMessage()));
121: }
122:
123: return true;
124: }
125:
126: public function sessionRead($id)
127: {
128:
129: $db_table = $this->options['db_table'];
130: $db_data_col = $this->options['db_data_col'];
131: $db_id_col = $this->options['db_id_col'];
132:
133: try
134: {
135: $sql = 'SELECT '.$db_data_col.' FROM '.$db_table.' WHERE '.$db_id_col.'=?';
136:
137: $stmt = $this->dbh->prepare($sql);
138: $stmt->bindParam(1, $id, PDO::PARAM_STR, 255);
139:
140: $stmt->execute();
141: $sessionRows = $stmt->fetchAll(PDO::FETCH_NUM);
142:
143: if (1 === count($sessionRows)) {
144: return $sessionRows[0][0];
145: } else {
146:
147: $this->createSession($id, '');
148: return false;
149: }
150: }
151: catch (PDOException $e)
152: {
153: throw new Exception(sprintf('Unable to read session data. Message: %s', $e->getMessage()));
154: }
155: }
156:
157: public function sessionWrite($id, $data)
158: {
159:
160: $db_table = $this->options['db_table'];
161: $db_data_col = $this->options['db_data_col'];
162: $db_id_col = $this->options['db_id_col'];
163: $db_time_col = $this->options['db_time_col'];
164:
165: $sessionExist = $this->dbh->fetchCol('SELECT COUNT(*) FROM '.$db_table.' WHERE '.$db_id_col.' = ?',$id);
166:
167: if($sessionExist)
168: {
169: try
170: {
171: $dt = new DateTime('now');
172: $dt->modify('+'.$this->ttl.' seconds');
173: $date = $dt->format("Y-m-d H:i:s");
174:
175: $this->dbh->update($db_table, array(
176: $db_id_col => $id,
177: $db_data_col => $data,
178: $db_time_col => $date
179: ),"$db_id_col = '$id'");
180: }
181: catch (PDOException $e)
182: {
183: throw new Exception(sprintf('Unable to write session data. Message: %s', $e->getMessage()));
184: }
185: }
186: else
187: {
188: $this->createSession($id, $data);
189: }
190:
191: return true;
192: }
193:
194: private function createSession($id,$data)
195: {
196: $dt = new DateTime('now');
197: $dt->modify('+'.$this->ttl.' seconds');
198: $date = $dt->format("Y-m-d H:i:s");
199: $this->dbh->insert($this->options['db_table'], array(
200: $this->options['db_id_col'] => $id,
201: $this->options['db_data_col'] => $data,
202: $this->options['db_time_col'] => $date
203: ));
204: }
205: }