ホームページ > バックエンド開発 > PHPチュートリアル > PHPで設定したcurl_multi関数の使い方

PHPで設定したcurl_multi関数の使い方

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
リリース: 2016-07-28 08:26:23
オリジナル
1105 人が閲覧しました

1. はじめに

この時期かなり忙しくて、長い間ブログを書いていませんでした。今日は、curl_multi_* 関数セットの使用に関する私の経験と http リクエストの問題について話します。

ユーザー php が http リクエストを開始したとき。まず何を使用することを考えますか?そうです、リクエストに応じてcurlを作成します。 1 回の実行で複数の http リクエストを開始する必要がある場合はどうなるでしょうか。これは簡単で、URL ごとに URL リクエストを作成します。 1本目をプレイしてから2本目をプレイしてほしいとのリクエスト…これで終わりですか?他に何が言えますか?

公式サイトリンク: http://php.net/manual/zh/book.curl.php

2. 複数の単純なcurlリクエストのデメリット

         php中curl_multi函数集的用法

クリをあげましょう。現在 3 つの http リクエストがあります。各リクエストには 2 秒かかります。単純なcurlリクエストに従う場合(図1-(1))。 6秒もかかったのは耐えられない。リクエストが多ければ多いほど、時間がかかります。

クエリ時間を短縮する方法はありますか? 3つのhttpリクエストを同時に実行できますか(図1-(1))。この問題を解決して時間を 2 秒に短縮する方法はたくさんあります。例: マルチプロセス、スレッド、イベント ループ、curl_multi_* など。最も簡単な方法は、curl_multi_* 関数を使用することです。実際、curl_multi_* の内部実装ではイベント ループが使用されます。

3. シンプルなcurl_multi_*アプリケーション

<code><span><?php</span><span>/**
 *
 * curl_multi_*简单运用
 *
 *<span> @author</span>: rudy
 *<span> @date</span>: 2016/07/12
 */</span><span>/**
 * 根据url,postData获取curl请求对象,这个比较简单,可以看官方文档
 */</span><span><span>function</span><span>getCurlObject</span><span>(<span>$url</span>,<span>$postData</span>=array<span>()</span>,<span>$header</span>=array<span>()</span>)</span>{</span><span>$options</span> = <span>array</span>();
    <span>$url</span> = trim(<span>$url</span>);
    <span>$options</span>[CURLOPT_URL] = <span>$url</span>;
    <span>$options</span>[CURLOPT_TIMEOUT] = <span>10</span>;
    <span>$options</span>[CURLOPT_USERAGENT] = <span>'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36'</span>;
    <span>$options</span>[CURLOPT_RETURNTRANSFER] = <span>true</span>;
    <span>//    $options[CURLOPT_PROXY] = '127.0.0.1:8888';</span><span>foreach</span>(<span>$header</span><span>as</span><span>$key</span>=><span>$value</span>){
        <span>$options</span>[<span>$key</span>] =<span>$value</span>;
    }
    <span>if</span>(!<span>empty</span>(<span>$postData</span>) && is_array(<span>$postData</span>)){
        <span>$options</span>[CURLOPT_POST] = <span>true</span>;
        <span>$options</span>[CURLOPT_POSTFIELDS] = http_build_query(<span>$postData</span>);
    }
    <span>if</span>(stripos(<span>$url</span>,<span>'https'</span>) === <span>0</span>){
        <span>$options</span>[CURLOPT_SSL_VERIFYPEER] = <span>false</span>;
    }
    <span>$ch</span> = curl_init();
    curl_setopt_array(<span>$ch</span>,<span>$options</span>);

    <span>return</span><span>$ch</span>;
}

<span>// 创建三个待请求的url对象</span><span>$chList</span> = <span>array</span>();
<span>$chList</span>[] = getCurlObject(<span>'https://www.baidu.com'</span>);
<span>$chList</span>[] = getCurlObject(<span>'http://www.jd.com'</span>);
<span>$chList</span>[] = getCurlObject(<span>'http://www.jianshu.com/'</span>);

<span>// 创建多请求执行对象</span><span>$downloader</span> = curl_multi_init();

<span>// 将三个待请求对象放入下载器中</span><span>foreach</span> (<span>$chList</span><span>as</span><span>$ch</span>){
    curl_multi_add_handle(<span>$downloader</span>,<span>$ch</span>);
}

<span>// 轮询</span><span>do</span> {
    <span>while</span> ((<span>$execrun</span> = curl_multi_exec(<span>$downloader</span>, <span>$running</span>)) == CURLM_CALL_MULTI_PERFORM) ;
    <span>if</span> (<span>$execrun</span> != CURLM_OK) {
        <span>break</span>;
    }

    <span>// 一旦有一个请求完成,找出来,处理,因为curl底层是select,所以最大受限于1024</span><span>while</span> (<span>$done</span> = curl_multi_info_read(<span>$downloader</span>))
    {
        <span>// 从请求中获取信息、内容、错误</span><span>$info</span> = curl_getinfo(<span>$done</span>[<span>'handle'</span>]);
        <span>$output</span> = curl_multi_getcontent(<span>$done</span>[<span>'handle'</span>]);
        <span>$error</span> = curl_error(<span>$done</span>[<span>'handle'</span>]);

        <span>// 将请求结果保存,我这里是打印出来</span><span>print</span><span>$output</span>;
<span>//        print "一个请求下载完成!\n";</span><span>// 把请求已经完成了得 curl handle 删除</span>
        curl_multi_remove_handle(<span>$downloader</span>, <span>$done</span>[<span>'handle'</span>]);
    }

    <span>// 当没有数据的时候进行堵塞,把 CPU 使用权交出来,避免上面 do 死循环空跑数据导致 CPU 100%</span><span>if</span> (<span>$running</span>) {
        <span>$rel</span> = curl_multi_select(<span>$downloader</span>, <span>1</span>);
        <span>if</span>(<span>$rel</span> == -<span>1</span>){
            usleep(<span>1000</span>);
        }
    }

    <span>if</span>( <span>$running</span> == <span>false</span>){
        <span>break</span>;
    }
} <span>while</span> (<span>true</span>);

<span>// 下载完毕,关闭下载器</span>
curl_multi_close(<span>$downloader</span>);
<span>echo</span><span>"所有请求下载完成!"</span>;</span></code>
ログイン後にコピー

この例では、まずリクエストするURLリクエストオブジェクトを3つ以上作成します。 curl_multi_* 関数を使用してダウンローダーを作成します。リクエストをダウンローダーに書き込みます。最後の投票。現在 3 つのリクエストが完了するのを待っています。加工を行います。

4. 複雑なcurl_multi_*の使用法

これがcurl_multi_*の使用方法ですか?シンプルすぎる!上の例では。ダウンローダー $downloader 内のリクエストは最初から追加されます。ダウンローダーにリクエストを動的に追加できますか。完了したリクエストをダウンローダーから動的に取得します。考えてみてください。これは何ですか?これがクローラーの中核部分、つまりダイナミックダウンローダーではないでしょうか。動的に追加するにはどうすればよいですか?マルチプロセスを使用して IPC 経由で追加できます。コルーチンを介してキューに待機を追加できます。

コルーチン+curl_multi_*を介してクローラーフレームワークを実装しました。
Tspider: https://github.com/hirudy/Tspider。
1 つのプロセスで 2000 ~ 5000/分のリクエストを処理できます。

').addClass('事前番号付け').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i ').text(i)); }; $numbering.fadeIn(1700); }); });

上記は、PHP で設定されたcurl_multi関数の使用法を、関連する内容も含めて紹介しました。PHP チュートリアルに興味のある友人に役立つことを願っています。

関連ラベル:
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート