From dec708cca33e7554a96a2b5c3c2c716474a2f41e Mon Sep 17 00:00:00 2001 From: erwin Date: Wed, 3 Dec 2025 19:11:42 +0100 Subject: [PATCH 01/11] Fix PHP 8.4 session_set_save_handler() deprecation --- framework/web/CHttpSession.php | 73 +++++++++++++++++++++--- tests/framework/web/CHttpSessionTest.php | 54 +++++++++++++++++- 2 files changed, 119 insertions(+), 8 deletions(-) diff --git a/framework/web/CHttpSession.php b/framework/web/CHttpSession.php index c33e2ffff..0004f3a32 100644 --- a/framework/web/CHttpSession.php +++ b/framework/web/CHttpSession.php @@ -109,13 +109,27 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar return false; } - /** - * Starts the session if it has not started yet. - */ - public function open() - { - if($this->getUseCustomStorage()) - @session_set_save_handler(array($this,'openSession'),array($this,'closeSession'),array($this,'readSession'),array($this,'writeSession'),array($this,'destroySession'),array($this,'gcSession')); + /** + * Starts the session if it has not started yet. + */ + public function open() + { + if ($this->getUseCustomStorage()) { + // PHP 8.4+ deprecates callback-style session_set_save_handler(). + // Use object-style handler on PHP 8.0+ to avoid deprecation. + if (PHP_VERSION_ID >= 80000) { + session_set_save_handler(new CHttpSessionHandler($this), true); + } else { + @session_set_save_handler( + array($this, 'openSession'), + array($this, 'closeSession'), + array($this, 'readSession'), + array($this, 'writeSession'), + array($this, 'destroySession'), + array($this, 'gcSession') + ); + } + } @session_start(); if(YII_DEBUG && session_id()=='') @@ -657,3 +671,48 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar $this->unfreeze(); } } + +/** + * SessionHandlerInterface adapter for CHttpSession. + * Delegates all calls to CHttpSession's openSession/closeSession/etc. methods, + * allowing subclasses like CDbHttpSession to work without modification. + */ +class CHttpSessionHandler implements SessionHandlerInterface +{ + private CHttpSession $_session; + + public function __construct(CHttpSession $session) + { + $this->_session = $session; + } + + public function open(string $path, string $name): bool + { + return $this->_session->openSession($path, $name); + } + + public function close(): bool + { + return $this->_session->closeSession(); + } + + public function read(string $id): string|false + { + return $this->_session->readSession($id); + } + + public function write(string $id, string $data): bool + { + return $this->_session->writeSession($id, $data); + } + + public function destroy(string $id): bool + { + return $this->_session->destroySession($id); + } + + public function gc(int $max_lifetime): int|false + { + return $this->_session->gcSession($max_lifetime) ? 0 : false; + } +} diff --git a/tests/framework/web/CHttpSessionTest.php b/tests/framework/web/CHttpSessionTest.php index cab82abf4..f4f33a9a0 100644 --- a/tests/framework/web/CHttpSessionTest.php +++ b/tests/framework/web/CHttpSessionTest.php @@ -1,5 +1,17 @@ markTestSkipped('session_set_save_handler() deprecation is PHP 8.4+ only.'); + } + + $deprecationTriggered = false; + set_error_handler(function ($errno, $errstr) use (&$deprecationTriggered) { + if ($errno === E_DEPRECATED && strpos($errstr, 'session_set_save_handler') !== false) { + $deprecationTriggered = true; + } + return false; + }, E_DEPRECATED); + + try { + $session = new CustomStorageSession(); + $session->setCookieMode('none'); + $session->setSavePath(sys_get_temp_dir()); + $session->setSessionName('CHttpSessionPhp84Test'); + $session->setTimeout(5); + + $session->open(); + + $this->assertNotSame('', session_id()); + $this->assertFalse($deprecationTriggered, 'session_set_save_handler() deprecation was triggered'); + } finally { + if (session_id() !== '') { + $session->close(); + } + restore_error_handler(); + } + } +} From 5d3ab97192f91b62cbb8fe904aa0391b1485ff28 Mon Sep 17 00:00:00 2001 From: erwin Date: Wed, 3 Dec 2025 19:32:28 +0100 Subject: [PATCH 02/11] Fix PHP 8.4 session handler compatibility and add return type hints --- framework/web/CHttpSession.php | 53 +++++++++++++++++++++++++++++----- 1 file changed, 45 insertions(+), 8 deletions(-) diff --git a/framework/web/CHttpSession.php b/framework/web/CHttpSession.php index 0004f3a32..8675bafc0 100644 --- a/framework/web/CHttpSession.php +++ b/framework/web/CHttpSession.php @@ -117,7 +117,7 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar if ($this->getUseCustomStorage()) { // PHP 8.4+ deprecates callback-style session_set_save_handler(). // Use object-style handler on PHP 8.0+ to avoid deprecation. - if (PHP_VERSION_ID >= 80000) { + if (PHP_VERSION_ID >= 70000) { session_set_save_handler(new CHttpSessionHandler($this), true); } else { @session_set_save_handler( @@ -679,39 +679,76 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar */ class CHttpSessionHandler implements SessionHandlerInterface { - private CHttpSession $_session; + /** + * @var CHttpSession + */ + private $_session; + /** + * @param CHttpSession $session + */ public function __construct(CHttpSession $session) { $this->_session = $session; } - public function open(string $path, string $name): bool + /** + * @param string $path + * @param string $name + * @return bool + */ + #[ReturnTypeWillChange] + public function open($path, $name) { return $this->_session->openSession($path, $name); } - public function close(): bool + /** + * @return bool + */ + #[ReturnTypeWillChange] + public function close() { return $this->_session->closeSession(); } - public function read(string $id): string|false + /** + * @param string $id + * @return string|false + */ + #[ReturnTypeWillChange] + public function read($id) { return $this->_session->readSession($id); } - public function write(string $id, string $data): bool + /** + * @param string $id + * @param string $data + * @return bool + */ + #[ReturnTypeWillChange] + public function write($id, $data) { return $this->_session->writeSession($id, $data); } - public function destroy(string $id): bool + /** + * @param string $id + * @return bool + */ + #[ReturnTypeWillChange] + public function destroy($id) { return $this->_session->destroySession($id); } - public function gc(int $max_lifetime): int|false + /** + * @param int $max_lifetime + * @return int|false + */ + #[ReturnTypeWillChange] + public function gc($max_lifetime) { return $this->_session->gcSession($max_lifetime) ? 0 : false; } From f682544dfc35f2526ce82f195a20a851988de94e Mon Sep 17 00:00:00 2001 From: erwin Date: Wed, 3 Dec 2025 19:40:55 +0100 Subject: [PATCH 03/11] Remove unnecessary try-finally block in session handler test --- tests/framework/web/CHttpSessionTest.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/framework/web/CHttpSessionTest.php b/tests/framework/web/CHttpSessionTest.php index f4f33a9a0..8acd05ba0 100644 --- a/tests/framework/web/CHttpSessionTest.php +++ b/tests/framework/web/CHttpSessionTest.php @@ -71,7 +71,6 @@ class CHttpSessionTest extends CTestCase { return false; }, E_DEPRECATED); - try { $session = new CustomStorageSession(); $session->setCookieMode('none'); $session->setSavePath(sys_get_temp_dir()); @@ -82,11 +81,10 @@ class CHttpSessionTest extends CTestCase { $this->assertNotSame('', session_id()); $this->assertFalse($deprecationTriggered, 'session_set_save_handler() deprecation was triggered'); - } finally { + if (session_id() !== '') { $session->close(); } restore_error_handler(); } - } } From a27cf8c18fc2bc32eafee8fa82aa881622eae8d9 Mon Sep 17 00:00:00 2001 From: erwin Date: Wed, 3 Dec 2025 19:51:59 +0100 Subject: [PATCH 04/11] Move CHttpSessionHandler to separate file for PHP 5.3 compatibility --- framework/web/CHttpSession.php | 87 ++----------------------- framework/web/CHttpSessionHandler.php | 91 +++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 83 deletions(-) create mode 100644 framework/web/CHttpSessionHandler.php diff --git a/framework/web/CHttpSession.php b/framework/web/CHttpSession.php index 8675bafc0..8f5cef03a 100644 --- a/framework/web/CHttpSession.php +++ b/framework/web/CHttpSession.php @@ -116,8 +116,11 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar { if ($this->getUseCustomStorage()) { // PHP 8.4+ deprecates callback-style session_set_save_handler(). - // Use object-style handler on PHP 8.0+ to avoid deprecation. + // Use object-style handler on PHP 7.0+ to avoid deprecation. + // CHttpSessionHandler is in a separate file to avoid parse errors on PHP 5.3 + // where SessionHandlerInterface doesn't exist. if (PHP_VERSION_ID >= 70000) { + require_once(dirname(__FILE__) . '/CHttpSessionHandler.php'); session_set_save_handler(new CHttpSessionHandler($this), true); } else { @session_set_save_handler( @@ -671,85 +674,3 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar $this->unfreeze(); } } - -/** - * SessionHandlerInterface adapter for CHttpSession. - * Delegates all calls to CHttpSession's openSession/closeSession/etc. methods, - * allowing subclasses like CDbHttpSession to work without modification. - */ -class CHttpSessionHandler implements SessionHandlerInterface -{ - /** - * @var CHttpSession - */ - private $_session; - - /** - * @param CHttpSession $session - */ - public function __construct(CHttpSession $session) - { - $this->_session = $session; - } - - /** - * @param string $path - * @param string $name - * @return bool - */ - #[ReturnTypeWillChange] - public function open($path, $name) - { - return $this->_session->openSession($path, $name); - } - - /** - * @return bool - */ - #[ReturnTypeWillChange] - public function close() - { - return $this->_session->closeSession(); - } - - /** - * @param string $id - * @return string|false - */ - #[ReturnTypeWillChange] - public function read($id) - { - return $this->_session->readSession($id); - } - - /** - * @param string $id - * @param string $data - * @return bool - */ - #[ReturnTypeWillChange] - public function write($id, $data) - { - return $this->_session->writeSession($id, $data); - } - - /** - * @param string $id - * @return bool - */ - #[ReturnTypeWillChange] - public function destroy($id) - { - return $this->_session->destroySession($id); - } - - /** - * @param int $max_lifetime - * @return int|false - */ - #[ReturnTypeWillChange] - public function gc($max_lifetime) - { - return $this->_session->gcSession($max_lifetime) ? 0 : false; - } -} diff --git a/framework/web/CHttpSessionHandler.php b/framework/web/CHttpSessionHandler.php new file mode 100644 index 000000000..6bf962f96 --- /dev/null +++ b/framework/web/CHttpSessionHandler.php @@ -0,0 +1,91 @@ + + * @link https://www.yiiframework.com/ + * @copyright 2008-2013 Yii Software LLC + * @license https://www.yiiframework.com/license/ + */ + +/** + * SessionHandlerInterface adapter for CHttpSession. + * Delegates all calls to CHttpSession's openSession/closeSession/etc. methods, + * allowing subclasses like CDbHttpSession to work without modification. + */ +class CHttpSessionHandler implements SessionHandlerInterface +{ + /** + * @var CHttpSession + */ + private $_session; + + /** + * @param CHttpSession $session + */ + public function __construct(CHttpSession $session) + { + $this->_session = $session; + } + + /** + * @param string $path + * @param string $name + * @return bool + */ + #[ReturnTypeWillChange] + public function open($path, $name) + { + return $this->_session->openSession($path, $name); + } + + /** + * @return bool + */ + #[ReturnTypeWillChange] + public function close() + { + return $this->_session->closeSession(); + } + + /** + * @param string $id + * @return string|false + */ + #[ReturnTypeWillChange] + public function read($id) + { + return $this->_session->readSession($id); + } + + /** + * @param string $id + * @param string $data + * @return bool + */ + #[ReturnTypeWillChange] + public function write($id, $data) + { + return $this->_session->writeSession($id, $data); + } + + /** + * @param string $id + * @return bool + */ + #[ReturnTypeWillChange] + public function destroy($id) + { + return $this->_session->destroySession($id); + } + + /** + * @param int $max_lifetime + * @return int|false + */ + #[ReturnTypeWillChange] + public function gc($max_lifetime) + { + return $this->_session->gcSession($max_lifetime) ? 0 : false; + } +} From 58e20905d131d61f0510f89920d03e54ec092b45 Mon Sep 17 00:00:00 2001 From: erwin Date: Wed, 3 Dec 2025 20:04:14 +0100 Subject: [PATCH 05/11] Add error suppression to session_set_save_handler() call Maintains consistent behavior with legacy code path by suppressing "headers already sent" warnings in test environments. --- framework/web/CHttpSession.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/web/CHttpSession.php b/framework/web/CHttpSession.php index 8f5cef03a..8a14cd5ff 100644 --- a/framework/web/CHttpSession.php +++ b/framework/web/CHttpSession.php @@ -120,8 +120,8 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar // CHttpSessionHandler is in a separate file to avoid parse errors on PHP 5.3 // where SessionHandlerInterface doesn't exist. if (PHP_VERSION_ID >= 70000) { - require_once(dirname(__FILE__) . '/CHttpSessionHandler.php'); - session_set_save_handler(new CHttpSessionHandler($this), true); + require_once(dirname(__FILE__).'/CHttpSessionHandler.php'); + @session_set_save_handler(new CHttpSessionHandler($this), true); } else { @session_set_save_handler( array($this, 'openSession'), From 8c5400983e9fbacced861bc9e31720f657baa2e3 Mon Sep 17 00:00:00 2001 From: erwin Date: Thu, 4 Dec 2025 17:39:27 +0100 Subject: [PATCH 06/11] Fixed code formatting to match Yii 1 coding style --- framework/web/CHttpSession.php | 52 ++++----- framework/web/CHttpSessionHandler.php | 132 +++++++++++------------ tests/framework/web/CHttpSessionTest.php | 76 ++++++------- 3 files changed, 134 insertions(+), 126 deletions(-) diff --git a/framework/web/CHttpSession.php b/framework/web/CHttpSession.php index 8a14cd5ff..4a79a10fb 100644 --- a/framework/web/CHttpSession.php +++ b/framework/web/CHttpSession.php @@ -109,30 +109,34 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar return false; } - /** - * Starts the session if it has not started yet. - */ - public function open() - { - if ($this->getUseCustomStorage()) { - // PHP 8.4+ deprecates callback-style session_set_save_handler(). - // Use object-style handler on PHP 7.0+ to avoid deprecation. - // CHttpSessionHandler is in a separate file to avoid parse errors on PHP 5.3 - // where SessionHandlerInterface doesn't exist. - if (PHP_VERSION_ID >= 70000) { - require_once(dirname(__FILE__).'/CHttpSessionHandler.php'); - @session_set_save_handler(new CHttpSessionHandler($this), true); - } else { - @session_set_save_handler( - array($this, 'openSession'), - array($this, 'closeSession'), - array($this, 'readSession'), - array($this, 'writeSession'), - array($this, 'destroySession'), - array($this, 'gcSession') - ); - } - } + /** + * Starts the session if it has not started yet. + */ + public function open() + { + if($this->getUseCustomStorage()) + { + // PHP 8.4+ deprecates callback-style session_set_save_handler(). + // Use object-style handler on PHP 7.0+ to avoid deprecation. + // CHttpSessionHandler is in a separate file to avoid parse errors on PHP 5.3 + // where SessionHandlerInterface doesn't exist. + if(PHP_VERSION_ID >= 70000) + { + require_once(dirname(__FILE__) . '/CHttpSessionHandler.php'); + @session_set_save_handler(new CHttpSessionHandler($this), true); + } + else + { + @session_set_save_handler( + array($this, 'openSession'), + array($this, 'closeSession'), + array($this, 'readSession'), + array($this, 'writeSession'), + array($this, 'destroySession'), + array($this, 'gcSession') + ); + } + } @session_start(); if(YII_DEBUG && session_id()=='') diff --git a/framework/web/CHttpSessionHandler.php b/framework/web/CHttpSessionHandler.php index 6bf962f96..2e973535b 100644 --- a/framework/web/CHttpSessionHandler.php +++ b/framework/web/CHttpSessionHandler.php @@ -15,77 +15,77 @@ */ class CHttpSessionHandler implements SessionHandlerInterface { - /** - * @var CHttpSession - */ - private $_session; + /** + * @var CHttpSession + */ + private $_session; - /** - * @param CHttpSession $session - */ - public function __construct(CHttpSession $session) - { - $this->_session = $session; - } + /** + * @param CHttpSession $session + */ + public function __construct(CHttpSession $session) + { + $this->_session=$session; + } - /** - * @param string $path - * @param string $name - * @return bool - */ - #[ReturnTypeWillChange] - public function open($path, $name) - { - return $this->_session->openSession($path, $name); - } + /** + * @param string $path + * @param string $name + * @return bool + */ + #[ReturnTypeWillChange] + public function open($path, $name) + { + return $this->_session->openSession($path, $name); + } - /** - * @return bool - */ - #[ReturnTypeWillChange] - public function close() - { - return $this->_session->closeSession(); - } + /** + * @return bool + */ + #[ReturnTypeWillChange] + public function close() + { + return $this->_session->closeSession(); + } - /** - * @param string $id - * @return string|false - */ - #[ReturnTypeWillChange] - public function read($id) - { - return $this->_session->readSession($id); - } + /** + * @param string $id + * @return string|false + */ + #[ReturnTypeWillChange] + public function read($id) + { + return $this->_session->readSession($id); + } - /** - * @param string $id - * @param string $data - * @return bool - */ - #[ReturnTypeWillChange] - public function write($id, $data) - { - return $this->_session->writeSession($id, $data); - } + /** + * @param string $id + * @param string $data + * @return bool + */ + #[ReturnTypeWillChange] + public function write($id, $data) + { + return $this->_session->writeSession($id, $data); + } - /** - * @param string $id - * @return bool - */ - #[ReturnTypeWillChange] - public function destroy($id) - { - return $this->_session->destroySession($id); - } + /** + * @param string $id + * @return bool + */ + #[ReturnTypeWillChange] + public function destroy($id) + { + return $this->_session->destroySession($id); + } - /** - * @param int $max_lifetime - * @return int|false - */ - #[ReturnTypeWillChange] - public function gc($max_lifetime) - { - return $this->_session->gcSession($max_lifetime) ? 0 : false; - } + /** + * @param int $max_lifetime + * @return int|false + */ + #[ReturnTypeWillChange] + public function gc($max_lifetime) + { + return $this->_session->gcSession($max_lifetime) ? 0 : false; + } } diff --git a/tests/framework/web/CHttpSessionTest.php b/tests/framework/web/CHttpSessionTest.php index 8acd05ba0..b8a94ef89 100644 --- a/tests/framework/web/CHttpSessionTest.php +++ b/tests/framework/web/CHttpSessionTest.php @@ -7,10 +7,10 @@ Yii::import('system.web.CHttpSession'); */ class CustomStorageSession extends CHttpSession { - public function getUseCustomStorage() - { - return true; - } + public function getUseCustomStorage() + { + return true; + } } class CHttpSessionTest extends CTestCase { @@ -50,41 +50,45 @@ class CHttpSessionTest extends CTestCase { } } - /** - * On PHP 8.4+, using custom storage should not trigger a - * session_set_save_handler() deprecation anymore. - * - * @runInSeparateProcess - * @preserveGlobalState disabled - */ - public function testCustomStorageDoesNotTriggerSessionSetSaveHandlerDeprecationOnPhp84() - { - if (version_compare(PHP_VERSION, '8.4', '<')) { - $this->markTestSkipped('session_set_save_handler() deprecation is PHP 8.4+ only.'); - } + /** + * On PHP 8.4+, using custom storage should not trigger a + * session_set_save_handler() deprecation anymore. + * + * @runInSeparateProcess + * @preserveGlobalState disabled + */ + public function testCustomStorageDoesNotTriggerSessionSetSaveHandlerDeprecationOnPhp84() + { + if(version_compare(PHP_VERSION, '8.4', '<')) + { + $this->markTestSkipped('session_set_save_handler() deprecation is PHP 8.4+ only.'); + } - $deprecationTriggered = false; - set_error_handler(function ($errno, $errstr) use (&$deprecationTriggered) { - if ($errno === E_DEPRECATED && strpos($errstr, 'session_set_save_handler') !== false) { - $deprecationTriggered = true; - } - return false; - }, E_DEPRECATED); + $deprecationTriggered=false; + set_error_handler(function ($errno, $errstr) use (&$deprecationTriggered) + { + if($errno === E_DEPRECATED && strpos($errstr, 'session_set_save_handler') !== false) + { + $deprecationTriggered=true; + } + return false; + }, E_DEPRECATED); - $session = new CustomStorageSession(); - $session->setCookieMode('none'); - $session->setSavePath(sys_get_temp_dir()); - $session->setSessionName('CHttpSessionPhp84Test'); - $session->setTimeout(5); + $session=new CustomStorageSession(); + $session->setCookieMode('none'); + $session->setSavePath(sys_get_temp_dir()); + $session->setSessionName('CHttpSessionPhp84Test'); + $session->setTimeout(5); - $session->open(); + $session->open(); - $this->assertNotSame('', session_id()); - $this->assertFalse($deprecationTriggered, 'session_set_save_handler() deprecation was triggered'); + $this->assertNotSame('', session_id()); + $this->assertFalse($deprecationTriggered, 'session_set_save_handler() deprecation was triggered'); - if (session_id() !== '') { - $session->close(); - } - restore_error_handler(); - } + if(session_id() !== '') + { + $session->close(); + } + restore_error_handler(); + } } From 4ef3b36160ee00055bb8bb2a705a206d7aa0eb36 Mon Sep 17 00:00:00 2001 From: erwin Date: Tue, 9 Dec 2025 11:13:19 +0100 Subject: [PATCH 07/11] Refactor PHP version check to Yii 1 convention. --- framework/web/CHttpSession.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/web/CHttpSession.php b/framework/web/CHttpSession.php index 4a79a10fb..95a8a7e32 100644 --- a/framework/web/CHttpSession.php +++ b/framework/web/CHttpSession.php @@ -120,7 +120,7 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar // Use object-style handler on PHP 7.0+ to avoid deprecation. // CHttpSessionHandler is in a separate file to avoid parse errors on PHP 5.3 // where SessionHandlerInterface doesn't exist. - if(PHP_VERSION_ID >= 70000) + if(version_compare(PHP_VERSION, '7.0', '>=')) { require_once(dirname(__FILE__) . '/CHttpSessionHandler.php'); @session_set_save_handler(new CHttpSessionHandler($this), true); From c47ebf92a3939a55428fa3d1a9623fb56db618ec Mon Sep 17 00:00:00 2001 From: erwin Date: Tue, 9 Dec 2025 11:24:10 +0100 Subject: [PATCH 08/11] Update author information in CHttpSessionHandler class file --- framework/web/CHttpSessionHandler.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/web/CHttpSessionHandler.php b/framework/web/CHttpSessionHandler.php index 2e973535b..ade2182a8 100644 --- a/framework/web/CHttpSessionHandler.php +++ b/framework/web/CHttpSessionHandler.php @@ -2,7 +2,7 @@ /** * CHttpSessionHandler class file. * - * @author Qiang Xue + * @author EFH Sollewijn Gelpke * @link https://www.yiiframework.com/ * @copyright 2008-2013 Yii Software LLC * @license https://www.yiiframework.com/license/ From 64b2da0f9c45498d67e2316c493550e482f0a88f Mon Sep 17 00:00:00 2001 From: erwin Date: Tue, 9 Dec 2025 11:41:16 +0100 Subject: [PATCH 09/11] Refactor session handling in CHttpSessionTest to improve error management --- tests/framework/web/CHttpSessionTest.php | 34 ++++++++++++++---------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/tests/framework/web/CHttpSessionTest.php b/tests/framework/web/CHttpSessionTest.php index b8a94ef89..ca5437f48 100644 --- a/tests/framework/web/CHttpSessionTest.php +++ b/tests/framework/web/CHttpSessionTest.php @@ -65,6 +65,8 @@ class CHttpSessionTest extends CTestCase { } $deprecationTriggered=false; + $session=null; + set_error_handler(function ($errno, $errstr) use (&$deprecationTriggered) { if($errno === E_DEPRECATED && strpos($errstr, 'session_set_save_handler') !== false) @@ -74,21 +76,25 @@ class CHttpSessionTest extends CTestCase { return false; }, E_DEPRECATED); - $session=new CustomStorageSession(); - $session->setCookieMode('none'); - $session->setSavePath(sys_get_temp_dir()); - $session->setSessionName('CHttpSessionPhp84Test'); - $session->setTimeout(5); - - $session->open(); - - $this->assertNotSame('', session_id()); - $this->assertFalse($deprecationTriggered, 'session_set_save_handler() deprecation was triggered'); - - if(session_id() !== '') + try { - $session->close(); + $session=new CustomStorageSession(); + $session->setCookieMode('none'); + $session->setSavePath(sys_get_temp_dir()); + $session->setSessionName('CHttpSessionPhp84Test'); + $session->setTimeout(5); + + $session->open(); + + $this->assertNotSame('', session_id()); + $this->assertFalse($deprecationTriggered, 'session_set_save_handler() deprecation was triggered'); + } finally + { + if($session !== null && session_id() !== '') + { + $session->close(); + } + restore_error_handler(); } - restore_error_handler(); } } From 4ef0c1b444e52d87e98f0d1644f1c549cdb4b66a Mon Sep 17 00:00:00 2001 From: erwin Date: Tue, 9 Dec 2025 11:59:43 +0100 Subject: [PATCH 10/11] FIX: Remove finally to support PHP 5.3 session test cleanup --- tests/framework/web/CHttpSessionTest.php | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/framework/web/CHttpSessionTest.php b/tests/framework/web/CHttpSessionTest.php index ca5437f48..51dc9de97 100644 --- a/tests/framework/web/CHttpSessionTest.php +++ b/tests/framework/web/CHttpSessionTest.php @@ -88,13 +88,20 @@ class CHttpSessionTest extends CTestCase { $this->assertNotSame('', session_id()); $this->assertFalse($deprecationTriggered, 'session_set_save_handler() deprecation was triggered'); - } finally + } catch(Exception $e) { if($session !== null && session_id() !== '') { $session->close(); } restore_error_handler(); + throw $e; } + + if($session !== null && session_id() !== '') + { + $session->close(); + } + restore_error_handler(); } } From 320a6772f95f9de01a48f9446d6289d0f865260b Mon Sep 17 00:00:00 2001 From: Marco van 't Wout Date: Tue, 9 Dec 2025 15:07:50 +0100 Subject: [PATCH 11/11] Update CHANGELOG --- CHANGELOG | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG b/CHANGELOG index e46426747..1217784d5 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -5,6 +5,7 @@ Version 1.1.32 under development -------------------------------- - Enh #4587: Add socket connection support to `CRedisCache` (mateusmetzker) +- Bug #4578: PHP 8.4 compatibility: Fix deprecation in session_set_save_handler() (efhsg) - Bug #4591: Fix deprecation in `CCaptchaAction` for PHP 8.1+ (rob006) Version 1.1.31 April 10, 2025