编程

PHP 8.2 移除的功能 —— MySQLi 不再支持使用 libmysqli 编译

2083 2022-11-30 08:05:07

历史上 PHP 支持两个库来连接 MySQL 数据库。对于 mysqli 扩展和 pdo_mysql 扩展,这些库为连接、查询、检索和处理检索数据提供了底层的功能支持。

  • mysqlnd (MySQL Native Driver):PHP 项目的一部分,提供了现代性功能,诸如返回原生PHP 数据类型(比如 integer),像 PHP 内核那样进行内存管理,功能非常强大。
  • libmysql:一个 MySQL 提供的外部库,不提供 mysqlnd 的所有特性,并且有外部库的不足之处:诸如不能合理跟踪或控制内存使用,并且存在库版本不匹配额潜在风险。再者,libmysql 在 Windows 系统上不可用。
  • PHP 5.4 起,mysqlnd 成为了默认库。不过,可以通过编译时的配置项使用 libmysql 来编译 mysqli 和 pdo_mysql 扩展。
  • 从 PHP 8.2 起,不再支持使用 libmysql 编译 mysqli 扩展。

请注意,仍然可以使用 libmysql 编译 pdo_mysql 扩展,不过将来 pdo_mysql 扩展可能会放弃对 libmysql 的支持。

尝试使用 --with-mysqli=FILE 选项编译 mysqli,会导致编译配置时的配置错误:

./configure --with-mysqli=FOO
Linking mysqli against external library is no longer supported

不太可能会有很多的 PHP 编译会因这一更新而受影响。因为 mysqlnd 功能更加强大、更加安全的特性,而且作为 PHP 默认 MySQL 库使用很长时间了。

libmysql 支持的,而 mysqlnd 没有提供的主要特性是:

  • 支持自动重连。mysqlnd 从内部杜绝了这一特性,因为这一特性可能带来不可预测的风险。
  • 通过 LDAP 和 SASL 授权。

LDAP/SASL 授权支持可能会被添加到 mysqlnd ,这一功能有一个 PR 存在。

已经决定,libmysql-style 自动重连的功能不会添加到 mysqlnd 中。一般而言,数据库连接丢失会导致在应用尝试重新连接的地方抛出异常,或者关闭应用。

之前依赖于自动重连功能的应用,现在需要处理可能的异常,并尝试手动重连。 

mysqli::ping() 及 mysqli_ping()

如果检测到 mysqli.reconnect INI 配置,mysqli::ping() and mysqli_ping() 函数将支持自动重连。

随着 libmysql 支持的移除,这些函数将不再支持自动重连特性。

mysqli.reconnect INI 检测

libmysql 指定的 mysqli.reconnect INI 配置指令检测也将在 PHP 8.2 移除。这个值用于ping 功能不再支持自动连接。

设置这一指令不会导致任何错误或者警告,也不会再有任何效果。

mysqli_driver::$reconnect 属性移除

MySQLi 扩展提供了 mysqli_driver 类用来获取驱动信息(比如客户端版本),也用来配置驱动的特定特性:比如,由现将移除的 libmysql 库提供的重连特性。

mysqli_driver::$reconnect 属性类似于 mysqli.reconnect INI 指令。

在 PHP 8.2 及以后,mysqli_driver::$reconnect 属性将被移除。尝试读取会导致未定义属性的警告。尝试设置对驱动行为并无影响,会带来动态属性弃用的警告通知。

向下兼容性影响

libmysql 的移除不太可能影响通用的 PHP 编译版本。

在 cPanel 中,mysqli 扩展使用 mysqlnd 编译,要求在 cPanel 控制面板中启用 mysqlnd 和 nd_mysql  插件。

最可能不兼容的是,该更新导致缺乏自动重连功能。libmysql 自动重连特性从一开始就有点不可预测,理想的升级路径是,捕获 mysqli 异常,并手动重新建立连接,或者优雅地退出程序。