Merge branch 'master' into bugfix/4573-null-sortfield-php8

This commit is contained in:
Marco van 't Wout
2025-12-09 15:11:01 +01:00
committed by GitHub
4 changed files with 182 additions and 2 deletions

View File

@@ -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 #4573: PHP 8 compatibility: Fix deprecation warning in CArrayDataProvider (efhsg)
- Bug #4591: Fix deprecation in `CCaptchaAction` for PHP 8.1+ (rob006)

View File

@@ -115,7 +115,28 @@ class CHttpSession extends CApplicationComponent implements IteratorAggregate,Ar
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'));
{
// 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(version_compare(PHP_VERSION, '7.0', '>='))
{
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()=='')

View File

@@ -0,0 +1,91 @@
<?php
/**
* CHttpSessionHandler class file.
*
* @author EFH Sollewijn Gelpke <efhsg@live.nl>
* @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;
}
}

View File

@@ -1,5 +1,17 @@
<?php
Yii::import('system.web.CHttpSession');
/**
* Simple test subclass that forces useCustomStorage = true via getter.
*/
class CustomStorageSession extends CHttpSession
{
public function getUseCustomStorage()
{
return true;
}
}
class CHttpSessionTest extends CTestCase {
protected function checkProb($gcProb) {
@@ -37,4 +49,59 @@ class CHttpSessionTest extends CTestCase {
$gcProb = $gcProb / 9;
}
}
}
/**
* 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;
$session=null;
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');
} 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();
}
}