From 70d3e08c11ecb22092757ea274412d889750bee6 Mon Sep 17 00:00:00 2001 From: maxpozdeev Date: Thu, 27 Feb 2025 21:34:32 +0300 Subject: [PATCH] * do not write session data on every request --- src/includes/class.sessionhandler.php | 66 ++++++++++++++++++++++----- 1 file changed, 54 insertions(+), 12 deletions(-) diff --git a/src/includes/class.sessionhandler.php b/src/includes/class.sessionhandler.php index 6353953..2a885cb 100644 --- a/src/includes/class.sessionhandler.php +++ b/src/includes/class.sessionhandler.php @@ -2,17 +2,19 @@ /* This file is a part of myTinyTodo. - (C) Copyright 2021-2022 Max Pozdeev + (C) Copyright 2021-2025 Max Pozdeev Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details. */ -class MTTSessionHandler implements SessionHandlerInterface +class MTTSessionHandler implements SessionHandlerInterface, SessionUpdateTimestampHandlerInterface { /** * @var Database_Abstract */ private $db; + private $isEmptyData = false; + /** * @param string $path * @param string $name @@ -25,7 +27,9 @@ class MTTSessionHandler implements SessionHandlerInterface return true; } - /** @return bool */ + /** + * @return bool + */ public function close(): bool { return true; @@ -41,21 +45,27 @@ class MTTSessionHandler implements SessionHandlerInterface { // read session data if not expired $time = time(); - $expire = $time; $r = $this->db->sq("SELECT data,last_access,expires FROM {$this->db->prefix}sessions WHERE id = ?", [$id]); - if ( is_null($r) ) return ''; + if ( is_null($r) ) { + // We return '' instead of false to avoid warning + return ''; + } if ( (int)$r[2] < $time) { // maybe regenerate id? $r[0] = ''; } // update last access time and set expires in 14 days - // refresh once in a second - if ( $r[1] < $time ) { + // refresh every 8 hours + if ( $r[1] + 28800 < $time ) { $expire = $time + 14 * 86400; $this->db->ex("UPDATE {$this->db->prefix}sessions SET last_access=?,expires=? WHERE id = ?", array($time, $expire, $id) ); } + + if ($r[0] === '') { + $this->isEmptyData = true; + } return $r[0]; } @@ -67,17 +77,23 @@ class MTTSessionHandler implements SessionHandlerInterface */ public function write($id, $data): bool { + // Ignore empty sessions without changes + if ($this->isEmptyData && $data === '') + return true; + + $time = time(); + $expire = $time + 14 * 86400; + $exists = $this->db->sq("SELECT COUNT(*) FROM {$this->db->prefix}sessions WHERE id = ?", [$id]); if (!$exists) { // Create new session with 14 days lifetime - $expire = time() + 14 * 86400; - $this->db->ex("INSERT INTO {$this->db->prefix}sessions (id,data,expires) VALUES (?,?,?)", - array($id, $data, $expire) ); + $this->db->ex("INSERT INTO {$this->db->prefix}sessions (id,data,last_access,expires) VALUES (?,?,?,?)", + array($id, $data, $time, $expire) ); } else { // Update existing session - $this->db->ex("UPDATE {$this->db->prefix}sessions SET data = ? WHERE id = ?", - array($data, $id) ); + $this->db->ex("UPDATE {$this->db->prefix}sessions SET data = ?, last_access=?, expires=? WHERE id = ?", + array($data, $time, $expire, $id) ); } return true; } @@ -105,5 +121,31 @@ class MTTSessionHandler implements SessionHandlerInterface $this->db->ex("DELETE FROM {$this->db->prefix}sessions WHERE expires < $expire"); return $this->db->affected(); } + + + /** + * SessionUpdateTimestampHandlerInterface::validateId + * @param string $id + * @return bool + */ + public function validateId(string $id): bool + { + $r = $this->db->sq("SELECT COUNT(*) FROM {$this->db->prefix}sessions WHERE id = ?", [$id]); + if ($r) + return true; + return false; + } + + /** + * SessionUpdateTimestampHandlerInterface::updateTimestamp + * @param string $id + * @param string $data + * @return bool + */ + public function updateTimestamp(string $id, string $data): bool + { + // Warning if return false + return true; + } }