当前位置: 首页> 最新文章列表> curl_multi_add_handle 函数的基础用法详解,如何快速上手和理解它的工作原理?

curl_multi_add_handle 函数的基础用法详解,如何快速上手和理解它的工作原理?

gitbox 2025-08-28
<span><span><span class="hljs-meta">&lt;?php</span></span><span>
</span><span><span class="hljs-comment">// 本文档为学习和参考用途,介绍 PHP 中 curl_multi_add_handle 函数的基础使用方式。</span></span><span>
</span><span><span class="hljs-meta">?&gt;</span></span><span>
&lt;hr&gt;

</span><span><span class="hljs-comment"># curl_multi_add_handle 函数的基础用法详解,如何快速上手和理解它的工作原理?</span></span><span>

在使用 PHP 进行并发 HTTP 请求时,`curl_multi_add_handle` 是一个非常核心的函数。它配合 `curl_multi_init`、`curl_multi_exec` 等函数,可以实现并行地发送多个 cURL 请求,从而大大提高网络请求的效率。本文将详细介绍 `curl_multi_add_handle` 的基础用法,帮助你快速理解它的工作原理并动手实践。

</span><span><span class="hljs-comment">## 一、什么是 curl_multi_add_handle?</span></span><span>

`</span><span><span class="hljs-title function_ invoke__">curl_multi_add_handle</span></span><span>()` 是 PHP 中用于添加单个 cURL 请求(即 curl handle)到一个多 cURL 会话(multi handle)中的函数。它的作用是告诉 `curl_multi_exec`:“我这里有一个新的请求,请一并处理它”。

**函数签名:**

```php
</span><span><span class="hljs-keyword">bool</span></span><span> </span><span><span class="hljs-title function_ invoke__">curl_multi_add_handle</span></span><span>(CurlMultiHandle </span><span><span class="hljs-variable">$multi_handle</span></span><span>, CurlHandle </span><span><span class="hljs-variable">$ch</span></span><span>);
</span></span>

返回值是布尔值,表示添加是否成功。

二、为什么使用 curl_multi 系列函数?

在默认的 cURL 请求中,每次请求都是同步阻塞的,也就是说,只有前一个请求完成后,才能执行下一个。这在需要请求多个接口或网站数据时非常低效。而 curl_multi 系列函数的引入,提供了一种非阻塞的并发处理方案。

三、基本示例:并发请求多个 URL

下面是一个使用 curl_multi_add_handle 的完整示例,演示如何并行请求多个网页:

<span><span><span class="hljs-variable">$urls</span></span><span> = [
    </span><span><span class="hljs-string">"https://www.example.com/"</span></span><span>,
    </span><span><span class="hljs-string">"https://www.php.net/"</span></span><span>,
    </span><span><span class="hljs-string">"https://www.wikipedia.org/"</span></span><span>
];

</span><span><span class="hljs-variable">$multiHandle</span></span><span> = </span><span><span class="hljs-title function_ invoke__">curl_multi_init</span></span><span>();
</span><span><span class="hljs-variable">$curlHandles</span></span><span> = [];

</span><span><span class="hljs-comment">// 初始化每个请求并添加到 multi handle 中</span></span><span>
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$urls</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$url</span></span><span>) {
    </span><span><span class="hljs-variable">$ch</span></span><span> = </span><span><span class="hljs-title function_ invoke__">curl_init</span></span><span>();
    </span><span><span class="hljs-title function_ invoke__">curl_setopt_array</span></span><span>(</span><span><span class="hljs-variable">$ch</span></span><span>, [
        CURLOPT_URL =&gt; </span><span><span class="hljs-variable">$url</span></span><span>,
        CURLOPT_RETURNTRANSFER =&gt; </span><span><span class="hljs-literal">true</span></span><span>,
        CURLOPT_TIMEOUT =&gt; </span><span><span class="hljs-number">10</span></span><span>
    ]);
    </span><span><span class="hljs-title function_ invoke__">curl_multi_add_handle</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>, </span><span><span class="hljs-variable">$ch</span></span><span>);
    </span><span><span class="hljs-variable">$curlHandles</span></span><span>[] = </span><span><span class="hljs-variable">$ch</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">$multiHandle</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-title function_ invoke__">curl_multi_select</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>); </span><span><span class="hljs-comment">// 等待 I/O</span></span><span>
    }
} </span><span><span class="hljs-keyword">while</span></span><span> (</span><span><span class="hljs-variable">$active</span></span><span> &amp;&amp; </span><span><span class="hljs-variable">$status</span></span><span> == CURLM_OK);

</span><span><span class="hljs-comment">// 获取结果</span></span><span>
</span><span><span class="hljs-keyword">foreach</span></span><span> (</span><span><span class="hljs-variable">$curlHandles</span></span><span> </span><span><span class="hljs-keyword">as</span></span><span> </span><span><span class="hljs-variable">$ch</span></span><span>) {
    </span><span><span class="hljs-variable">$content</span></span><span> = </span><span><span class="hljs-title function_ invoke__">curl_multi_getcontent</span></span><span>(</span><span><span class="hljs-variable">$ch</span></span><span>);
    </span><span><span class="hljs-variable">$info</span></span><span> = </span><span><span class="hljs-title function_ invoke__">curl_getinfo</span></span><span>(</span><span><span class="hljs-variable">$ch</span></span><span>);
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"URL: "</span></span><span> . </span><span><span class="hljs-variable">$info</span></span><span>[</span><span><span class="hljs-string">'url'</span></span><span>] . </span><span><span class="hljs-string">"\n"</span></span><span>;
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"HTTP Code: "</span></span><span> . </span><span><span class="hljs-variable">$info</span></span><span>[</span><span><span class="hljs-string">'http_code'</span></span><span>] . </span><span><span class="hljs-string">"\n"</span></span><span>;
    </span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"Content Length: "</span></span><span> . </span><span><span class="hljs-title function_ invoke__">strlen</span></span><span>(</span><span><span class="hljs-variable">$content</span></span><span>) . </span><span><span class="hljs-string">"\n\n"</span></span><span>;
    </span><span><span class="hljs-title function_ invoke__">curl_multi_remove_handle</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>, </span><span><span class="hljs-variable">$ch</span></span><span>);
    </span><span><span class="hljs-title function_ invoke__">curl_close</span></span><span>(</span><span><span class="hljs-variable">$ch</span></span><span>);
}

</span><span><span class="hljs-title function_ invoke__">curl_multi_close</span></span><span>(</span><span><span class="hljs-variable">$multiHandle</span></span><span>);
</span></span>

四、工作原理简述

  1. 使用 curl_multi_init() 创建一个 multi handle。

  2. 对每个 URL 创建一个普通的 cURL handle,并设置好参数。

  3. 使用 curl_multi_add_handle() 把每个 handle 添加到 multi handle 中。

  4. 使用 curl_multi_exec() 启动所有请求的执行。

  5. 使用 curl_multi_select() 阻塞直到有活动连接。

  6. 处理完所有请求后,记得使用 curl_multi_remove_handle() 移除,并关闭所有句柄。

五、常见注意事项

六、总结

curl_multi_add_handle 是构建高性能网络请求的基础,理解它的角色有助于你更深入掌握 PHP 中的异步处理能力。掌握了它,就能够实现并发爬虫、多接口聚合请求等高级功能,大幅提升你的 PHP 程序在 I/O 密集型场景下的效率。

通过多练习示例代码,你将能更熟练地运用这个函数,写出更高效、专业的 PHP 程序。

<span></span>