35、PHP 8.4 方法或功能修改 - Curl:CURLOPT_DNS_USE_GLOBAL_CACHE 不再有任何效果
在 PHP 8.4 中,CURLOPT_DNS_USE_GLOBAL_CACHE 选项不再生效。这是由于该选项的功能在 libcurl 中被弃用,并且在 PHP 8.4 中已被移除。
背景和功能概述
CURLOPT_DNS_USE_GLOBAL_CACHE 选项是用于配置 Curl 是否使用全局 DNS 缓存的。启用此选项时,Curl 会在不同的请求之间共享 DNS 信息,而不需要每次请求时都进行 DNS 解析。当 Curl 使用这个选项时,即使 Curl 句柄被销毁,DNS 信息也会继续缓存,直到应用程序结束。
具体来说,使用 CURLOPT_DNS_USE_GLOBAL_CACHE 选项的作用是让 Curl 在多个请求之间共享一个全局的 DNS 缓存。这个选项通常是在执行频繁的 HTTP 请求时用于提高效率,尤其是在对多个域名进行请求时,减少了对 DNS 服务器的重复查询。
弃用和移除
libcurl 从版本 7.11.1 开始就已弃用 CURLOPT_DNS_USE_GLOBAL_CACHE 选项,并在版本 7.62.0 中完全移除。libcurl 的全局 DNS 缓存并不是线程安全的,这会导致在多线程环境中出现潜在的安全问题和错误行为。为了避免这些问题,libcurl 官方决定完全弃用这个选项。
在 PHP 8.4 中,CURLOPT_DNS_USE_GLOBAL_CACHE 选项被移除,无论所使用的 libcurl 版本如何,设置这个选项将没有任何效果。
推荐的 DNS 缓存方法
PHP 8.4 中,推荐使用以下方法来处理 DNS 缓存:
-
使用
CurlShareHandle
对象:为了在多个 Curl 请求之间共享 DNS 缓存,推荐使用 CurlShareHandle 对象。这可以通过调用
curl_share_init
函数创建一个共享句柄来实现,从而使得多个请求之间共享同一个 DNS 缓存。通过共享句柄,多个 Curl 句柄可以共享相同的资源(包括 DNS 缓存)。<?php // 初始化共享句柄 $share = curl_share_init(); // 创建第一个 Curl 句柄并与共享句柄关联 $ch1 = curl_init(); curl_share_setopt($ch1, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); curl_setopt($ch1, CURLOPT_URL, "https://qq.com"); // 创建第二个 Curl 句柄并与共享句柄关联 $ch2 = curl_init(); curl_share_setopt($ch2, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS); curl_setopt($ch2, CURLOPT_URL, "https://weixin.com"); // 执行请求 curl_exec($ch1); curl_exec($ch2); // 关闭 Curl 句柄和共享句柄 curl_close($ch1); curl_close($ch2); curl_share_close($share);
这段代码展示了如何通过
curl_share_init
创建一个共享句柄,使用它共享 DNS 数据,避免了使用已弃用的 CURLOPT_DNS_USE_GLOBAL_CACHE。 -
依赖系统 DNS 解析器:
如果你的 Curl 请求没有启用 DNS Over HTTPS(DoH),那么 Curl 将会依赖于系统的 DNS 解析器。在这种情况下,DNS 信息会被操作系统缓存,而不是由 libcurl 管理。操作系统的 DNS 缓存通常是线程安全的,且具有标准的刷新机制,这也是目前推荐的 DNS 缓存方式。
4. 向后兼容性影响
尽管 CURLOPT_DNS_USE_GLOBAL_CACHE 本身并未被完全弃用(它依旧存在,但不再有效),但是 PHP 应用程序中如果继续使用该选项,则可以安全地移除它,因为:
- 在 PHP 8.4 中,无论 libcurl 版本如何,设置 CURLOPT_DNS_USE_GLOBAL_CACHE 都不会产生任何效果。
- 对于线程安全的 PHP 构建,启用 CURLOPT_DNS_USE_GLOBAL_CACHE 时不再触发警告(如之前的 "启用线程安全时无法激活
CURLOPT_DNS_USE_GLOBAL_CACHE
" 警告)。