编程

PHP 8.4: 弃用使用两个以上参数调用 session_set_save_handler()

84 2024-11-03 04:19:00

Session 扩展中的 session_set_save_handler 函数设置了一系列用户级会话存储函数,以覆盖内置的基于文件的存储机制。当应用需要将用户会话存储在数据库、内存中,或在自动化测试期间覆盖会话存储机制时,这很有用。

session_set_save_handler 函数支持两个重载签名,这仅适用于原生内置的 PHP 函数,并且只有少数 PHP 函数可以s使用。重载函数签名被投票弃用,因为函数重载不支持用户空间的 PHP 函数,并且考虑到它们在静态分析、文档、验证等方面的问题。

有关重载函数的其他实例,请参阅带有重载签名的弃用函数 RFC。

session_set_save_handler 函数在 PHP>=5.4 和 PHP<9.0 中支持两个签名:

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

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

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());

下面是一个示例,通过将相同的回调封装在匿名类中,将现有的六个 callable 签名更改为 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 或更高版本兼容(由于使用了 Union 类型)。如果删除这些类型,则此实现与PHP>=5.4 跨版本兼容。

向后兼容性影响

PHP 8.4 不支持 session_set_save_handler 函数的重载签名变体,该函数接受六个或更多个单独的 callable 值。在 PHP 8.4 及更高版本中调用弃用签名会发出弃用通知。

该替换版本可以与 PHP 5.4+ 兼容。

在 PHP 9.0 中,重载的签名将被删除,试图使用现已弃用的签名调用 session_set_save_handler 函数将发出 \TypeError 异常。