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