15
15
use CodeIgniter \Session \Exceptions \SessionException ;
16
16
use Config \App as AppConfig ;
17
17
use Config \Database ;
18
- use Exception ;
18
+ use ReturnTypeWillChange ;
19
19
20
20
/**
21
21
* Session handler using current Database for storage
@@ -58,27 +58,24 @@ class DatabaseHandler extends BaseHandler
58
58
protected $ rowExists = false ;
59
59
60
60
/**
61
- * Constructor
61
+ * @throws SessionException
62
62
*/
63
63
public function __construct (AppConfig $ config , string $ ipAddress )
64
64
{
65
65
parent ::__construct ($ config , $ ipAddress );
66
-
67
- // Determine Table
68
66
$ this ->table = $ config ->sessionSavePath ;
69
67
70
68
if (empty ($ this ->table )) {
71
69
throw SessionException::forMissingDatabaseTable ();
72
70
}
73
71
74
- // Get DB Connection
75
72
// @phpstan-ignore-next-line
76
73
$ this ->DBGroup = $ config ->sessionDBGroup ?? config (Database::class)->defaultGroup ;
77
74
78
75
$ this ->db = Database::connect ($ this ->DBGroup );
79
76
80
- // Determine Database type
81
77
$ driver = strtolower (get_class ($ this ->db ));
78
+
82
79
if (strpos ($ driver , 'mysql ' ) !== false ) {
83
80
$ this ->platform = 'mysql ' ;
84
81
} elseif (strpos ($ driver , 'postgre ' ) !== false ) {
@@ -87,16 +84,12 @@ public function __construct(AppConfig $config, string $ipAddress)
87
84
}
88
85
89
86
/**
90
- * Open
91
- *
92
- * Ensures we have an initialized database connection.
93
- *
94
- * @param string $savePath Path to session files' directory
95
- * @param string $name Session cookie name
87
+ * Re-initialize existing session, or creates a new one.
96
88
*
97
- * @throws Exception
89
+ * @param string $path The path where to store/retrieve the session
90
+ * @param string $name The session name
98
91
*/
99
- public function open ($ savePath , $ name ): bool
92
+ public function open ($ path , $ name ): bool
100
93
{
101
94
if (empty ($ this ->db ->connID )) {
102
95
$ this ->db ->initialize ();
@@ -106,30 +99,29 @@ public function open($savePath, $name): bool
106
99
}
107
100
108
101
/**
109
- * Read
102
+ * Reads the session data from the session storage, and returns the results.
110
103
*
111
- * Reads session data and acquires a lock
104
+ * @param string $id The session ID
112
105
*
113
- * @param string $sessionID Session ID
114
- *
115
- * @return string Serialized session data
106
+ * @return false|string Returns an encoded string of the read data.
107
+ * If nothing was read, it must return false.
116
108
*/
117
- public function read ($ sessionID ): string
109
+ #[ReturnTypeWillChange]
110
+ public function read ($ id )
118
111
{
119
- if ($ this ->lockSession ($ sessionID ) === false ) {
112
+ if ($ this ->lockSession ($ id ) === false ) {
120
113
$ this ->fingerprint = md5 ('' );
121
114
122
115
return '' ;
123
116
}
124
117
125
- // Needed by write() to detect session_regenerate_id() calls
126
118
if (! isset ($ this ->sessionID )) {
127
- $ this ->sessionID = $ sessionID ;
119
+ $ this ->sessionID = $ id ;
128
120
}
129
121
130
122
$ builder = $ this ->db ->table ($ this ->table )
131
123
->select ($ this ->platform === 'postgre ' ? "encode(data, 'base64') AS data " : 'data ' )
132
- ->where ('id ' , $ sessionID );
124
+ ->where ('id ' , $ id );
133
125
134
126
if ($ this ->matchIP ) {
135
127
$ builder = $ builder ->where ('ip_address ' , $ this ->ipAddress );
@@ -160,87 +152,78 @@ public function read($sessionID): string
160
152
}
161
153
162
154
/**
163
- * Write
164
- *
165
- * Writes (create / update) session data
155
+ * Writes the session data to the session storage.
166
156
*
167
- * @param string $sessionID Session ID
168
- * @param string $sessionData Serialized session data
157
+ * @param string $id The session ID
158
+ * @param string $data The encoded session data
169
159
*/
170
- public function write ($ sessionID , $ sessionData ): bool
160
+ public function write ($ id , $ data ): bool
171
161
{
172
162
if ($ this ->lock === false ) {
173
163
return $ this ->fail ();
174
164
}
175
165
176
- // Was the ID regenerated?
177
- if ($ sessionID !== $ this ->sessionID ) {
166
+ if ($ this ->sessionID !== $ id ) {
178
167
$ this ->rowExists = false ;
179
- $ this ->sessionID = $ sessionID ;
168
+ $ this ->sessionID = $ id ;
180
169
}
181
170
182
171
if ($ this ->rowExists === false ) {
183
172
$ insertData = [
184
- 'id ' => $ sessionID ,
173
+ 'id ' => $ id ,
185
174
'ip_address ' => $ this ->ipAddress ,
186
175
'timestamp ' => 'now() ' ,
187
- 'data ' => $ this ->platform === 'postgre ' ? '\x ' . bin2hex ($ sessionData ) : $ sessionData ,
176
+ 'data ' => $ this ->platform === 'postgre ' ? '\x ' . bin2hex ($ data ) : $ data ,
188
177
];
189
178
190
179
if (! $ this ->db ->table ($ this ->table )->insert ($ insertData )) {
191
180
return $ this ->fail ();
192
181
}
193
182
194
- $ this ->fingerprint = md5 ($ sessionData );
183
+ $ this ->fingerprint = md5 ($ data );
195
184
$ this ->rowExists = true ;
196
185
197
186
return true ;
198
187
}
199
188
200
- $ builder = $ this ->db ->table ($ this ->table )->where ('id ' , $ sessionID );
189
+ $ builder = $ this ->db ->table ($ this ->table )->where ('id ' , $ id );
201
190
202
191
if ($ this ->matchIP ) {
203
192
$ builder = $ builder ->where ('ip_address ' , $ this ->ipAddress );
204
193
}
205
194
206
- $ updateData = [
207
- 'timestamp ' => 'now() ' ,
208
- ];
195
+ $ updateData = ['timestamp ' => 'now() ' ];
209
196
210
- if ($ this ->fingerprint !== md5 ($ sessionData )) {
211
- $ updateData ['data ' ] = ($ this ->platform === 'postgre ' ) ? '\x ' . bin2hex ($ sessionData ) : $ sessionData ;
197
+ if ($ this ->fingerprint !== md5 ($ data )) {
198
+ $ updateData ['data ' ] = ($ this ->platform === 'postgre ' ) ? '\x ' . bin2hex ($ data ) : $ data ;
212
199
}
213
200
214
201
if (! $ builder ->update ($ updateData )) {
215
202
return $ this ->fail ();
216
203
}
217
204
218
- $ this ->fingerprint = md5 ($ sessionData );
205
+ $ this ->fingerprint = md5 ($ data );
219
206
220
207
return true ;
221
208
}
222
209
223
210
/**
224
- * Close
225
- *
226
- * Releases locks and closes file descriptor.
211
+ * Closes the current session.
227
212
*/
228
213
public function close (): bool
229
214
{
230
215
return ($ this ->lock && ! $ this ->releaseLock ()) ? $ this ->fail () : true ;
231
216
}
232
217
233
218
/**
234
- * Destroy
235
- *
236
- * Destroys the current session.
219
+ * Destroys a session
237
220
*
238
- * @param string $sessionID
221
+ * @param string $id The session ID being destroyed
239
222
*/
240
- public function destroy ($ sessionID ): bool
223
+ public function destroy ($ id ): bool
241
224
{
242
225
if ($ this ->lock ) {
243
- $ builder = $ this ->db ->table ($ this ->table )->where ('id ' , $ sessionID );
226
+ $ builder = $ this ->db ->table ($ this ->table )->where ('id ' , $ id );
244
227
245
228
if ($ this ->matchIP ) {
246
229
$ builder = $ builder ->where ('ip_address ' , $ this ->ipAddress );
@@ -261,18 +244,20 @@ public function destroy($sessionID): bool
261
244
}
262
245
263
246
/**
264
- * Garbage Collector
247
+ * Cleans up expired sessions.
265
248
*
266
- * Deletes expired sessions
249
+ * @param int $max_lifetime Sessions that have not updated
250
+ * for the last max_lifetime seconds will be removed.
267
251
*
268
- * @param int $maxlifetime Maximum lifetime of sessions
252
+ * @return false| int Returns the number of deleted sessions on success, or false on failure.
269
253
*/
270
- public function gc ($ maxlifetime ): bool
254
+ #[ReturnTypeWillChange]
255
+ public function gc ($ max_lifetime )
271
256
{
272
257
$ separator = $ this ->platform === 'postgre ' ? '\'' : ' ' ;
273
- $ interval = implode ($ separator , ['' , "{$ maxlifetime } second " , '' ]);
258
+ $ interval = implode ($ separator , ['' , "{$ max_lifetime } second " , '' ]);
274
259
275
- return $ this ->db ->table ($ this ->table )->delete ("timestamp < now() - INTERVAL {$ interval }" ) ? true : $ this ->fail ();
260
+ return $ this ->db ->table ($ this ->table )->delete ("timestamp < now() - INTERVAL {$ interval }" ) ? 1 : $ this ->fail ();
276
261
}
277
262
278
263
/**
0 commit comments