43、PHP 8.4 中弃用 - 使用 2 个以上参数调用 session_set_save_handler() 已弃用

作者: 温新

图书: 【PHP 8.4 新特性】

阅读: 101

时间: 2025-01-18 07:56:28

session_set_save_handler 函数来自 PHP 的 session 扩展,它允许设置一系列用户级的会话存储函数,以覆盖内置的基于文件的存储机制。这在需要将用户会话存储到数据库、内存中,或在自动化测试过程中覆盖会话存储机制时非常有用。

session_set_save_handler 函数支持两种重载签名,这是只有原生内建 PHP 函数才支持的特性,且只有少数 PHP 函数会利用这一特性。函数重载签名正逐步被淘汰,因为函数重载不是用户自定义 PHP 函数支持的特性,且在静态分析、文档生成、验证等方面存在问题。

关于其他重载函数的实例,可以参考“弃用带有重载签名的函数” RFC。

PHP >= 5.4 和 PHP < 9.0 中 session_set_save_handler 的两个签名

1.传递单独的回调函数

function session_set_save_handler2(
    callable $open,
    callable $close,
    callable $read,
    callable $write,
    callable $destroy,
    callable $gc,
    ?callable $create_sid = null,
    ?callable $validate_sid = null,
    ?callable $update_timestamp = null
): bool

此函数签名需要六个必需的回调函数参数,并支持三个可选的回调函数参数。

2. 传递 SessionHandlerInterface 实例

function session_set_save_handler(SessionHandlerInterface $sessionhandler, bool $register_shutdown = true): bool

SessionHandlerInterface 声明了诸如 openclosereadwritedestroygc 等方法,这些方法的调用方式与第一个签名中的单独回调函数类似。

调用 session_set_save_handler 超过两个参数已弃用

作为“弃用带有重载签名的函数” RFC 的一部分,session_set_save_handler 函数的第一个签名(传递单独的回调函数)已被弃用。

这意味着,像下面这样的调用将会触发弃用通知:

session_set_save_handler('my_session_open', 'my_session_close', 'my_session_read', 'my_session_write', 'my_session_destroy', 'my_session_gc');

弃用通知

Deprecated: Calling session_set_save_handler() with more than 2 arguments is deprecated in ... on line ...

在 PHP 9.0 中,PHP 将不再支持这个签名。

推荐替代方案

由于在 PHP 8.4 中调用 session_set_save_handler 时传递超过两个参数已被弃用,因此 PHP 应用程序应使用上述第二个签名。

如果应用程序使用单独的函数来处理会话,它们将不得不声明一个实现了 SessionHandlerInterface 接口的会话处理类,或者使用匿名类。

使用 SessionHandlerInterface 替换回调的示例:

session_set_save_handler('my_session_open', 'my_session_close', 'my_session_read', 'my_session_write', 'my_session_destroy', 'my_session_gc');
session_set_save_handler(new MySessionHandler());

这是一个通过将相同的回调函数包装在匿名类中,将现有的六个回调签名更改为 SessionHandlerInterface 签名的示例。虽然这是最少修改的方式,但建议创建一个新的实现了 SessionHandlerInterface 接口的类,并使用它。

session_set_save_handler('my_session_open', 'my_session_close', 'my_session_read', 'my_session_write', 'my_session_destroy', 'my_session_gc');
$sessionHandler = new class() implements SessionHandlerInterface {
    public function open(string $path, string $name): bool {
        return my_session_open($path, $name);
    }

    public function close(): bool {
        return my_session_close();
    }

    public function read(string $id): string|false {
        return my_session_read($id);
    }

    public function write(string $id, string $data): bool {
        return my_session_write($id, $data);
    }

    public function destroy(string $id): bool {
        return my_session_destroy($id);
    }

    public function gc(int $max_lifetime): int|false {
        return my_session_gc($max_lifetime);
    }
};

session_set_save_handler($sessionHandler);

上述示例应与 PHP 8.0 或更高版本兼容(由于使用了联合类型)。如果去掉类型声明,这个实现与 PHP >= 5.4 版本兼容。

向后兼容性影响

PHP 8.4 弃用了 session_set_save_handler 函数的重载签名版本,该版本接受六个或更多单独的回调函数参数。在 PHP 8.4 及以后的版本中调用该弃用签名会触发弃用通知。

替代方案与 PHP 5.4 及更高版本兼容。

该重载签名将在 PHP 9.0 中被移除,尝试使用已弃用的签名调用 session_set_save_handler 函数将会触发 \TypeError 异常。

请登录后再评论