PHP sessions are great for dealing with log in systems, tracking user activity, and allowing them to save data as they move around your site, like a shopping cart. Writing up what you need to run it though can be a bit painful, so that’s what lead me onto creating a custom session handling class in PHP.
The script handles sessions within a database to allow it to be more secure and analytically useful. It’s derived from an article by Richard Willars who I owe a lot to for the basis of this script. Anything that I don’t cover will be available on his website.
Here is the script:
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 | /* Session class by Stephen McIntyre http://stephenmcintyre.net */ class Session { private $id = ''; private $alive = true; private $dbc = NULL; function __construct() { session_set_save_handler( array(&$this, 'open'), array(&$this, 'close'), array(&$this, 'read'), array(&$this, 'write'), array(&$this, 'destroy'), array(&$this, 'clean')); session_start(); } function __destruct() { if($this->alive) { session_write_close(); $this->alive = false; } } function delete() { if(ini_get('session.use_cookies')) { $params = session_get_cookie_params(); setcookie(session_name(), '', time() - 42000, $params['path'], $params['domain'], $params['secure'], $params['httponly'] ); } session_destroy(); $this->alive = false; } private function open() { $this->dbc = new MYSQLi(DB_HOST, DB_USERNAME, DB_PASSWORD, DB_NAME) OR die('Could not connect to database.'); return true; } private function close() { return $this->dbc->close(); } private function read($sid) { $this->id = $sid; $q = "SELECT `data` FROM `sessions` WHERE `id` = '".$this->dbc->real_escape_string($sid)."' LIMIT 1"; $r = $this->dbc->query($q); if($r->num_rows == 1) { $fields = $r->fetch_assoc(); return $fields['data']; } else { return ''; } } private function write($sid, $data) { $q = "REPLACE INTO `sessions` (`id`, `data`) VALUES ('".$this->dbc->real_escape_string($sid)."', '".$this->dbc->real_escape_string($data)."')"; $this->dbc->query($q); return $this->dbc->affected_rows; } private function destroy($sid) { $q = "DELETE FROM `sessions` WHERE `id` = '".$this->dbc->real_escape_string($sid)."'"; $this->dbc->query($q); $_SESSION = array(); return $this->dbc->affected_rows; } private function clean($expire) { $q = "DELETE FROM `sessions` WHERE DATE_ADD(`sesh_last_accessed`, INTERVAL ".(int) $expire." SECOND) < NOW()"; $this->dbc->query($q); return $this->dbc->affected_rows; } } |
Before you try to use the class you have to set up your database. I have used exactly the same database setup as Richard here, but can easily be expanded into using user IDs and shopping carts as I mentioned before.
1 2 3 4 5 6 | CREATE TABLE `sessions` ( `id` char(32) NOT NULL, `data` longtext NOT NULL, `last_accessed` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; |
If you use phpMyAdmin it’s as simple as adding a database as you normally would and pasting the above into the SQL query box.
For the class to connect to the database, you also need to create some definitions in PHP.
1 2 3 4 | define('DB_USERNAME', 'root'); define('DB_PASSWORD', ''); define('DB_NAME', 'penguin'); define('DB_HOST', 'localhost'); |
This should be placed at the top of your PHP file, replacing the appropriate fields with your own database information.
That’s it set up. All you have to do now is call it in one line.
1 | $session = new Session(); |
And set our session data with the $_SESSION variable as usual.
1 2 | $session = new Session(); $_SESSION['user_id'] = 1; |
The user ID above will then be stored inside the “data” field in your database, in a serialised format that the class will be able to parse.
Since it’s handled from a class, the variable will also call session_write_close(); by itself when the page ends, so no need to call this yourself. If you want to end it early though, you can always call the destructor manually.
1 2 3 | $session = new Session(); // ... extra code ... $session->__destruct(); |
The session can also be deleted (like when logging out) and to do this we just call the delete method.
1 2 3 | $session = new Session(); // ... extra code ... $session->delete(); |
So there you have it, a simple session handling class you can use for any web project.
Also, if you do use this in your applications, please be kind enough to leave the extra header text at the top.
Thanks
Untold Entertain...
Untold Entertain...
Untold Entertain...