<?php

/**
 * php version: 5.6.17
 */
date_default_timezone_set('asia/shanghai');
error_reporting(0);
$urls = array('https://item.taobao.com/item.htm?spm=a1z10.1-c.w4024-11308530054.1.oOFbdH&id=520625892808&scene=taobao_shop', 'https://item.taobao.com/item.htm?spm=a1z10.3777-c.w4986-13288965637.2.j19e7O&id=522054508511', 'http://item.jd.com/1256491.html', 'http://item.jd.com/1385518.html');
$options = array(CURL_RETURNTRANSFER => 1);
$response = rolling_curl($urls, $options);
echo '<pre>';
print_r($response);
exit;
/**
 * 不再像classic_curl那样等待所有请求完成之后再进行后面的处理
 * 而是边请求边返回边处理
 */
function rolling_curl($urls, $options)
{
    $queue = curl_multi_init();
    $map = array();
    foreach ($urls as $url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt_array($ch, $options);
        curl_multi_add_handle($queue, $ch);
        $map[$ch] = $url;
    }
    $response = array();
    do {
        while (($code = curl_multi_exec($queue, $active)) == CURLM_CALL_MULTI_PERFORM) {
        while (($code = curl_multi_exec($queue, $active)) == CURLM_CALL_MULTI_PERFORM) {
        }
        if ($code != CURLM_OK) {
            break;
        }
        // a request was just completed -- find out which one
        while ($done = curl_multi_info_read($queue)) {
            // get the info and content returned on the request
            $info = curl_getinfo($done['handle']);
            $error = curl_error($done['handle']);
            $results = curl_multi_getcontent($done['handle']);
            $responses[$map[(string) $done['handle']]] = compact('info', 'error', 'results');
            // remove the curl handle that just completed
            curl_multi_remove_handle($queue, $done['handle']);
            curl_close($done['handle']);
        }
        // Block for data in / output; error handling is done by curl_multi_exec
        if ($active > 0) {
            curl_multi_select($queue, 0.5);
        }
    } while ($active);
    curl_multi_close($queue);
    return $responses;
}
function callback($data, $delay)
{
    usleep($delay);
    return $data;
}
$re = rolling_curl($urls, 5);
echo $re;
Example #3
0
<?php

//include "curl.php";
$url = 'http://xxx.com?t=';
echo "start at " . date('r') . "\n";
$res = rolling_curl(["{$url}2", "{$url}3"]);
var_dump($res);
echo "end at " . date('r') . "\n";
function rolling_curl($urls)
{
    $queue = curl_multi_init();
    $map = array();
    foreach ($urls as $url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_TIMEOUT, 50);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_multi_add_handle($queue, $ch);
        $map[] = $ch;
    }
    $active = null;
    // execute the handles
    $responses = [];
    do {
        //If curl_multi_exec returns CURLM_CALL_MULTI_PERFORM, select simply blocks for $timeout and returns -1. So we shoud made a full_curl_multi_exec before multi_select
        while (($mrc = curl_multi_exec($queue, $active)) === CURLM_CALL_MULTI_PERFORM) {
        }
        //get new state(new activity connection)
        //Error occurs
        if ($mrc != CURLM_OK) {
            break;