mirror of
https://github.com/yiisoft/yii2.git
synced 2025-11-03 13:58:55 +08:00
Fix #20140: Fix compatibility with PHP 8.4: calling session_set_save_handler()
This commit is contained in:
committed by
GitHub
parent
5df412df2c
commit
65e3369e16
@ -18,6 +18,7 @@ Yii Framework 2 Change Log
|
|||||||
- New #20279: Add to the `\yii\web\Request` CSRF validation by custom HTTP header (olegbaturin)
|
- New #20279: Add to the `\yii\web\Request` CSRF validation by custom HTTP header (olegbaturin)
|
||||||
- Enh #20279: Add to the `\yii\web\Request` `csrfHeader` property to configure a custom HTTP header for CSRF validation (olegbaturin)
|
- Enh #20279: Add to the `\yii\web\Request` `csrfHeader` property to configure a custom HTTP header for CSRF validation (olegbaturin)
|
||||||
- Enh #20279: Add to the `\yii\web\Request` `csrfTokenSafeMethods` property to configure a custom safe HTTP methods list (olegbaturin)
|
- Enh #20279: Add to the `\yii\web\Request` `csrfTokenSafeMethods` property to configure a custom safe HTTP methods list (olegbaturin)
|
||||||
|
- Bug #20140: Fix compatibility with PHP 8.4: calling `session_set_save_handler()` (Izumi-kun)
|
||||||
|
|
||||||
2.0.51 July 18, 2024
|
2.0.51 July 18, 2024
|
||||||
--------------------
|
--------------------
|
||||||
|
|||||||
@ -51,6 +51,13 @@ if you want to upgrade from version A to version C and there is
|
|||||||
version B between A and C, you need to follow the instructions
|
version B between A and C, you need to follow the instructions
|
||||||
for both A and B.
|
for both A and B.
|
||||||
|
|
||||||
|
Upgrade from Yii 2.0.51
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
* The function signature for `yii\web\Session::readSession()` and `yii\web\Session::gcSession()` have been changed.
|
||||||
|
They now have the same return types as `\SessionHandlerInterface::read()` and `\SessionHandlerInterface::gc()` respectively.
|
||||||
|
In case those methods have overwritten you will need to update your child classes accordingly.
|
||||||
|
|
||||||
Upgrade from Yii 2.0.50
|
Upgrade from Yii 2.0.50
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
|||||||
@ -92,7 +92,7 @@ class CacheSession extends Session
|
|||||||
* Session read handler.
|
* Session read handler.
|
||||||
* @internal Do not call this method directly.
|
* @internal Do not call this method directly.
|
||||||
* @param string $id session ID
|
* @param string $id session ID
|
||||||
* @return string the session data
|
* @return string|false the session data, or false on failure
|
||||||
*/
|
*/
|
||||||
public function readSession($id)
|
public function readSession($id)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -171,7 +171,7 @@ class DbSession extends MultiFieldSession
|
|||||||
* Session read handler.
|
* Session read handler.
|
||||||
* @internal Do not call this method directly.
|
* @internal Do not call this method directly.
|
||||||
* @param string $id session ID
|
* @param string $id session ID
|
||||||
* @return string the session data
|
* @return string|false the session data, or false on failure
|
||||||
*/
|
*/
|
||||||
public function readSession($id)
|
public function readSession($id)
|
||||||
{
|
{
|
||||||
@ -247,15 +247,13 @@ class DbSession extends MultiFieldSession
|
|||||||
* Session GC (garbage collection) handler.
|
* Session GC (garbage collection) handler.
|
||||||
* @internal Do not call this method directly.
|
* @internal Do not call this method directly.
|
||||||
* @param int $maxLifetime the number of seconds after which data will be seen as 'garbage' and cleaned up.
|
* @param int $maxLifetime the number of seconds after which data will be seen as 'garbage' and cleaned up.
|
||||||
* @return bool whether session is GCed successfully
|
* @return int|false the number of deleted sessions on success, or false on failure
|
||||||
*/
|
*/
|
||||||
public function gcSession($maxLifetime)
|
public function gcSession($maxLifetime)
|
||||||
{
|
{
|
||||||
$this->db->createCommand()
|
return $this->db->createCommand()
|
||||||
->delete($this->sessionTable, '[[expire]]<:expire', [':expire' => time()])
|
->delete($this->sessionTable, '[[expire]]<:expire', [':expire' => time()])
|
||||||
->execute();
|
->execute();
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -175,34 +175,23 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co
|
|||||||
static::$_originalSessionModule = $sessionModuleName;
|
static::$_originalSessionModule = $sessionModuleName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($this->handler === null && $this->getUseCustomStorage()) {
|
||||||
|
$this->handler = Yii::createObject(
|
||||||
|
[
|
||||||
|
'__class' => SessionHandler::class,
|
||||||
|
'__construct()' => [$this],
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->handler !== null) {
|
if ($this->handler !== null) {
|
||||||
if (!is_object($this->handler)) {
|
if (is_array($this->handler)) {
|
||||||
$this->handler = Yii::createObject($this->handler);
|
$this->handler = Yii::createObject($this->handler);
|
||||||
}
|
}
|
||||||
if (!$this->handler instanceof \SessionHandlerInterface) {
|
if (!$this->handler instanceof \SessionHandlerInterface) {
|
||||||
throw new InvalidConfigException('"' . get_class($this) . '::handler" must implement the SessionHandlerInterface.');
|
throw new InvalidConfigException('"' . get_class($this) . '::handler" must implement the SessionHandlerInterface.');
|
||||||
}
|
}
|
||||||
YII_DEBUG ? session_set_save_handler($this->handler, false) : @session_set_save_handler($this->handler, false);
|
YII_DEBUG ? session_set_save_handler($this->handler, false) : @session_set_save_handler($this->handler, false);
|
||||||
} elseif ($this->getUseCustomStorage()) {
|
|
||||||
if (YII_DEBUG) {
|
|
||||||
session_set_save_handler(
|
|
||||||
[$this, 'openSession'],
|
|
||||||
[$this, 'closeSession'],
|
|
||||||
[$this, 'readSession'],
|
|
||||||
[$this, 'writeSession'],
|
|
||||||
[$this, 'destroySession'],
|
|
||||||
[$this, 'gcSession']
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
@session_set_save_handler(
|
|
||||||
[$this, 'openSession'],
|
|
||||||
[$this, 'closeSession'],
|
|
||||||
[$this, 'readSession'],
|
|
||||||
[$this, 'writeSession'],
|
|
||||||
[$this, 'destroySession'],
|
|
||||||
[$this, 'gcSession']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} elseif (
|
} elseif (
|
||||||
$sessionModuleName !== static::$_originalSessionModule
|
$sessionModuleName !== static::$_originalSessionModule
|
||||||
&& static::$_originalSessionModule !== null
|
&& static::$_originalSessionModule !== null
|
||||||
@ -610,7 +599,7 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co
|
|||||||
* This method should be overridden if [[useCustomStorage]] returns true.
|
* This method should be overridden if [[useCustomStorage]] returns true.
|
||||||
* @internal Do not call this method directly.
|
* @internal Do not call this method directly.
|
||||||
* @param string $id session ID
|
* @param string $id session ID
|
||||||
* @return string the session data
|
* @return string|false the session data, or false on failure
|
||||||
*/
|
*/
|
||||||
public function readSession($id)
|
public function readSession($id)
|
||||||
{
|
{
|
||||||
@ -647,11 +636,11 @@ class Session extends Component implements \IteratorAggregate, \ArrayAccess, \Co
|
|||||||
* This method should be overridden if [[useCustomStorage]] returns true.
|
* This method should be overridden if [[useCustomStorage]] returns true.
|
||||||
* @internal Do not call this method directly.
|
* @internal Do not call this method directly.
|
||||||
* @param int $maxLifetime the number of seconds after which data will be seen as 'garbage' and cleaned up.
|
* @param int $maxLifetime the number of seconds after which data will be seen as 'garbage' and cleaned up.
|
||||||
* @return bool whether session is GCed successfully
|
* @return int|false the number of deleted sessions on success, or false on failure
|
||||||
*/
|
*/
|
||||||
public function gcSession($maxLifetime)
|
public function gcSession($maxLifetime)
|
||||||
{
|
{
|
||||||
return true;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
79
framework/web/SessionHandler.php
Normal file
79
framework/web/SessionHandler.php
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @link https://www.yiiframework.com/
|
||||||
|
* @copyright Copyright (c) 2008 Yii Software LLC
|
||||||
|
* @license https://www.yiiframework.com/license/
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace yii\web;
|
||||||
|
|
||||||
|
use SessionHandlerInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* SessionHandler implements an [[\SessionHandlerInterface]] for handling [[Session]] with custom session storage.
|
||||||
|
*
|
||||||
|
* @author Viktor Khokhryakov <viktor.khokhryakov@gmail.com>
|
||||||
|
* @since 2.0.52
|
||||||
|
*/
|
||||||
|
class SessionHandler implements SessionHandlerInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var Session
|
||||||
|
*/
|
||||||
|
private $_session;
|
||||||
|
|
||||||
|
public function __construct(Session $session)
|
||||||
|
{
|
||||||
|
$this->_session = $session;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function close(): bool
|
||||||
|
{
|
||||||
|
return $this->_session->closeSession();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function destroy($id): bool
|
||||||
|
{
|
||||||
|
return $this->_session->destroySession($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
|
public function gc($max_lifetime)
|
||||||
|
{
|
||||||
|
return $this->_session->gcSession($max_lifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function open($path, $name): bool
|
||||||
|
{
|
||||||
|
return $this->_session->openSession($path, $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
#[\ReturnTypeWillChange]
|
||||||
|
public function read($id)
|
||||||
|
{
|
||||||
|
return $this->_session->readSession($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @inheritDoc
|
||||||
|
*/
|
||||||
|
public function write($id, $data): bool
|
||||||
|
{
|
||||||
|
return $this->_session->writeSession($id, $data);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -127,8 +127,9 @@ abstract class AbstractDbSessionTest extends TestCase
|
|||||||
$session->db->createCommand()
|
$session->db->createCommand()
|
||||||
->update('session', ['expire' => time() - 100], 'id = :id', ['id' => 'expire'])
|
->update('session', ['expire' => time() - 100], 'id = :id', ['id' => 'expire'])
|
||||||
->execute();
|
->execute();
|
||||||
$session->gcSession(1);
|
$deleted = $session->gcSession(1);
|
||||||
|
|
||||||
|
$this->assertEquals(1, $deleted);
|
||||||
$this->assertEquals('', $session->readSession('expire'));
|
$this->assertEquals('', $session->readSession('expire'));
|
||||||
$this->assertEquals('new data', $session->readSession('new'));
|
$this->assertEquals('new data', $session->readSession('new'));
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user