编程

PHP 8.1 - IMAP扩展:imap 资源使用 IMAP\Connection 类对象

1103 2023-04-26 03:19:00

PHP 8.1 中,imap 扩展的 IMAP 连接资源迁移到了类对象上。

PHP 8.1 之前,imap_open() 函数返回一个 imap 类型的资源对象。从 PHP 8.1 开始,它返回 IMAP\Connection 类实例。 

所有之前接受资源类型参数的函数,现在也接受新类型。

资源到对象的迁移
PHP 正在使用类对象逐步淘汰所有 resource 类型,这个迁移只是资源到对象迁移计划的一部分。

扩展空间改变
该迁移遵循 PHP 新提出的将命名空间用于捆绑扩展的规范.

IMAP\Connection 类摘要

namespace IMAP;
final class Connection {}

与其他资源到对象迁移语义一致,新的 IMAP\Connection 类也被声明为 final 类,以最大限度地减少 PHP 修改该类的实现细节时潜在的向后兼容性中断。

imap_open 函数仍然用于创建 IMAP\Connection 类实例,并且不允许使用新的 IMAP\Connection() 构造进行实例化:

new IMAP\Connection();
Cannot directly construct IMAP\Connection, use imap_open() instead

由于 IMAP\Connection 类声明未 final,不允许对其扩展。

class Foo extends IMAP\Connection {}
PHP Fatal error:  Class Foo may not inherit from final class (IMAP\Connection) in ... on line ...

is_resource 检测

使用 is_resource 函数检测所有迁移到类对象的资源,不再返回 true;而且用 is_resource 函数检测 IMAP 资源有效性的旧代码在 PHP 8.1 以上版本会带来问题。

所有的 PHP 版本中,imap_open 函数在未能创建 IMAP 资源时,都会返回 false。在 PHP 8.1 及以后也是如此。

现有代码中要检测给定的变量中的 IMAP 连接是否有效,在 PHP 8.1 及以上版本需要考虑 IMAP\Connection 类对象返回值。

- is_resource($imap_connection)
+ is_resource($imap_connection) || $imap_connection instanceof \IMAP\Connection

另外,检测其是否为 false 可能更为合适且可读,且可在跨版本中适用。

- is_resource($imap_connection)
+ $imap_connection !== false

关闭 IMAP\Connection 资源

IMAP 资源会在 IMAP\Connection 不再`被引用时()关闭,或使用 unset($connection) 显式销毁时 关闭。

用于关闭 imap 资源的 imap_clode 函数,仍然可用。

尝试使用已关闭的 IMAP\Connection 对象会导致 \ValueError 异常。

ValueError: IMAP\Connection is already closed

向后兼容性影响

和其他资源到对象迁移一样,IMAP 扩展无缝升级返回及接受新的基于类对象的资源作为参数。

is_resource 函数现在对 IMAP 连接对象返回 false,而不是之前的 true。 如果适用该函数检测 IMAP 连接资源,这里可能会有兼容性问题。