当前位置: 首页> 最新文章列表> curl_multi_info_read 如何帮你实时获取多个 cURL 线程请求的执行状态?

curl_multi_info_read 如何帮你实时获取多个 cURL 线程请求的执行状态?

gitbox 2025-08-13

在开发涉及多个 HTTP 请求的 PHP 程序时,尤其是进行大量 API 请求时,使用 cURL 是常见的选择。为了提升效率,PHP 提供了一个多线程 cURL 处理函数 curl_multi_*,可以并行地发送多个请求。这使得程序可以同时处理多个请求,而不是一个接一个地等待响应。

但是,当我们使用多线程 cURL 时,我们不仅需要发送请求,还需要实时获取每个请求的执行状态、错误信息、返回的内容等数据。curl_multi_info_read() 函数便是帮助我们获取这些信息的工具之一。

1. 什么是 curl_multi_info_read()?

curl_multi_info_read() 函数是 PHP 中一个用于获取多个并行 cURL 请求执行状态的函数。通过它,开发者可以在多个请求并行的情况下,实时监控每个请求的执行进度和状态。该函数会返回一个包含当前请求状态的数组,包括 HTTP 状态码、请求是否成功等信息。

2. 如何使用 curl_multi_info_read()?

要使用 curl_multi_info_read(),你需要先通过 curl_multi_init() 初始化一个多线程 cURL 会话,然后通过 curl_multi_add_handle() 将多个单独的 cURL 句柄添加到这个会话中。最后,你可以通过 curl_multi_exec() 让请求并行执行,使用 curl_multi_info_read() 获取每个请求的执行状态。

以下是一个简单的例子:

<span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-comment">// 初始化多线程 cURL 会话</span></span><span>
</span><span><span class="hljs-variable">$mh</span></span><span> = </span><span><span class="hljs-title function_ invoke__">curl_multi_init</span></span><span>();

</span><span><span class="hljs-comment">// 创建多个 cURL 句柄</span></span><span>
</span><span><span class="hljs-variable">$ch1</span></span><span> = </span><span><span class="hljs-title function_ invoke__">curl_init</span></span><span>(</span><span><span class="hljs-string">"https://www.example.com"</span></span><span>);
</span><span><span class="hljs-variable">$ch2</span></span><span> = </span><span><span class="hljs-title function_ invoke__">curl_init</span></span><span>(</span><span><span class="hljs-string">"https://www.example.org"</span></span><span>);

</span><span><span class="hljs-comment">// 设置 cURL 选项</span></span><span>
</span><span><span class="hljs-title function_ invoke__">curl_setopt</span></span><span>(</span><span><span class="hljs-variable">$ch1</span></span><span>, CURLOPT_RETURNTRANSFER, </span><span><span class="hljs-literal">true</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">curl_setopt</span></span><span>(</span><span><span class="hljs-variable">$ch2</span></span><span>, CURLOPT_RETURNTRANSFER, </span><span><span class="hljs-literal">true</span></span><span>);

</span><span><span class="hljs-comment">// 将 cURL 句柄添加到多线程会话中</span></span><span>
</span><span><span class="hljs-title function_ invoke__">curl_multi_add_handle</span></span><span>(</span><span><span class="hljs-variable">$mh</span></span><span>, </span><span><span class="hljs-variable">$ch1</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">curl_multi_add_handle</span></span><span>(</span><span><span class="hljs-variable">$mh</span></span><span>, </span><span><span class="hljs-variable">$ch2</span></span><span>);

</span><span><span class="hljs-comment">// 执行请求</span></span><span>
</span><span><span class="hljs-keyword">do</span></span><span> {
    </span><span><span class="hljs-variable">$status</span></span><span> = </span><span><span class="hljs-title function_ invoke__">curl_multi_exec</span></span><span>(</span><span><span class="hljs-variable">$mh</span></span><span>, </span><span><span class="hljs-variable">$active</span></span><span>);
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$active</span></span><span>) {
        </span><span><span class="hljs-comment">// 等待请求完成</span></span><span>
        </span><span><span class="hljs-title function_ invoke__">curl_multi_select</span></span><span>(</span><span><span class="hljs-variable">$mh</span></span><span>);
    }
} </span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-variable">$active</span></span><span>);

</span><span><span class="hljs-comment">// 获取每个请求的执行状态</span></span><span>
</span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-variable">$info</span></span><span> = </span><span><span class="hljs-title function_ invoke__">curl_multi_info_read</span></span><span>(</span><span><span class="hljs-variable">$mh</span></span><span>)) {
    </span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$info</span></span><span>[</span><span><span class="hljs-string">'result'</span></span><span>] === CURLE_OK) {
        </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Request to "</span></span><span> . </span><span><span class="hljs-variable">$info</span></span><span>[</span><span><span class="hljs-string">'handle'</span></span><span>] . </span><span><span class="hljs-string">" succeeded.\n"</span></span><span>;
    } </span><span><span class="hljs-keyword">else</span></span><span> {
        </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Request to "</span></span><span> . </span><span><span class="hljs-variable">$info</span></span><span>[</span><span><span class="hljs-string">'handle'</span></span><span>] . </span><span><span class="hljs-string">" failed with error: "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">curl_error</span></span><span>(</span><span><span class="hljs-variable">$info</span></span><span>[</span><span><span class="hljs-string">'handle'</span></span><span>]) . </span><span><span class="hljs-string">"\n"</span></span><span>;
    }
}

</span><span><span class="hljs-comment">// 清理</span></span><span>
</span><span><span class="hljs-title function_ invoke__">curl_multi_remove_handle</span></span><span>(</span><span><span class="hljs-variable">$mh</span></span><span>, </span><span><span class="hljs-variable">$ch1</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">curl_multi_remove_handle</span></span><span>(</span><span><span class="hljs-variable">$mh</span></span><span>, </span><span><span class="hljs-variable">$ch2</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">curl_multi_close</span></span><span>(</span><span><span class="hljs-variable">$mh</span></span><span>);
</span><span><span class="hljs-meta">?&gt;</span></span><span>
</span></span>

3. 函数详解

curl_multi_info_read() 会返回一个包含请求信息的数组,其中包括以下字段:

  • handle:对应的 cURL 句柄。

  • result:执行结果。如果值为 CURLE_OK,表示请求成功。如果请求失败,返回相应的错误代码。

  • msg:返回的消息类型(通常为 CURLMSG_DONE,表示请求已完成)。

该函数会返回一个数组,如果没有更多的请求信息,它将返回 null

4. 实时监控多个请求的状态

在进行多个并行请求时,程序的执行效率会大大提高,尤其是当请求之间没有直接依赖关系时。利用 curl_multi_info_read(),我们可以实时地监控每个请求的状态,确保在请求完成时能够及时获取到相关信息,处理异常或者获取返回数据。

通过 curl_multi_info_read(),我们能够:

  • 获取请求的执行状态:确认请求是否成功。

  • 捕获请求的错误信息:如果请求失败,可以即时获取错误代码,便于后续处理。

  • 实时获取请求的响应数据:如果请求成功,获取返回的数据并进行处理。

5. 实际应用场景

在一些需要批量处理 HTTP 请求的场景中,curl_multi_info_read() 变得尤为重要。例如:

  • 批量数据抓取:同时请求多个网站,获取数据并解析。

  • 并行 API 调用:当多个外部 API 需要被调用时,可以同时发起请求,获取返回数据。

  • 大规模并发请求:高效地发送并处理多个请求,避免阻塞。

6. 总结

curl_multi_info_read() 在 PHP 中提供了一个强大且实用的工具,用于获取多个 cURL 请求的执行状态。通过合理地使用该函数,我们可以轻松监控并行请求的进展、捕获错误信息以及获取请求结果,极大提升多请求任务的执行效率。无论是在爬虫开发、批量数据抓取,还是并行 API 调用中,curl_multi_info_read() 都是不可或缺的利器。

  • 相关标签:

    cURL