2

我需要一个接一个地向同一个域发出许多 curl 请求,但不能并行发出它们。

我在http://technosophos.com/找到了以下代码示例

这确实可以很好地加快重复的 curl 调用。

function get2($url) {
// Create a handle.
$handle = curl_init($url);

 // Set options...

 // Do the request.
 $ret = curlExecWithMulti($handle);

 // Do stuff with the results...

 // Destroy the handle.
 curl_close($handle);


   }

   function curlExecWithMulti($handle) {

// In real life this is a class variable.
  static $multi = NULL;

 // Create a multi if necessary.
if (empty($multi)) {
 $multi = curl_multi_init();
  }

 // Add the handle to be processed.
 curl_multi_add_handle($multi, $handle);

 // Do all the processing.
  $active = NULL;
do {
 $ret = curl_multi_exec($multi, $active);
 } while ($ret == CURLM_CALL_MULTI_PERFORM);

 while ($active && $ret == CURLM_OK) {
    if (curl_multi_select($multi) != -1) {
   do {
      $mrc = curl_multi_exec($multi, $active);
    } while ($mrc == CURLM_CALL_MULTI_PERFORM);
  }
}

 // Remove the handle from the multi processor.
 curl_multi_remove_handle($multi, $handle);

 return TRUE;
 }

我已经多次尝试通过设置 curl 选项来获取函数 curlExecWithMulti($handle) 以将 curl 的结果作为变量返回,但到目前为止没有成功。

这可以做到吗?

4

1 回答 1

4

也许这会很有趣,很容易理解。它会执行您的 curl 多请求,然后返回一组结果,它还会执行 curl POST。

<?php
//demo receiver
if($_SERVER['REQUEST_METHOD']=='POST'){
    echo $_POST['post_var'];
    die;
}

/**
 * CURL GET|POST Multi
 */
function curl_multi($data, $options = array()) {
    $curly = array();
    $result = array();

    $mh = curl_multi_init();
    foreach ($data as $id=>$d) {
        $curly[$id] = curl_init();
        $url = (is_array($d) && !empty($d['url'])) ? $d['url'] : $d;

        $header[0]="Accept: text/xml,application/xml,application/xhtml+xml,application/json";
        $header[0].="text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5";
        $header[]="Cache-Control: max-age=0";
        $header[]="Connection: keep-alive";
        $header[]="Keep-Alive: 2";
        $header[]="Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7";
        $header[]="Accept-Language: en-us,en;q=0.5";
        $header[]="Pragma: ";
        curl_setopt($curly[$id], CURLOPT_URL,            $url);
        curl_setopt($curly[$id], CURLOPT_HEADER,         0);
        curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curly[$id], CURLOPT_TIMEOUT,        30);
        curl_setopt($curly[$id], CURLOPT_USERAGENT,      "cURL (http://".$_SERVER['SERVER_NAME'].")");
        curl_setopt($curly[$id], CURLOPT_HTTPHEADER,     $header);
        curl_setopt($curly[$id], CURLOPT_REFERER,        $url);
        curl_setopt($curly[$id], CURLOPT_ENCODING,       'gzip,deflate');
        curl_setopt($curly[$id], CURLOPT_AUTOREFERER,    true);
        curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, true);
        // post?
        if (is_array($d)) {
            if (!empty($d['post'])) {
                curl_setopt($curly[$id], CURLOPT_POST,       1);
                curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $d['post']);
            }
        }
        // extra options?
        if (!empty($options)) {
            curl_setopt_array($curly[$id], $options);
        }
        curl_multi_add_handle($mh, $curly[$id]);
    }
    $running = null;
    do {
        curl_multi_exec($mh, $running);
    } while($running > 0);
    foreach($curly as $id => $c) {
        $result[$id] = curl_multi_getcontent($c);
        curl_multi_remove_handle($mh, $c);
    }
    curl_multi_close($mh);
    return $result;
}

$request = array(
    array('url'=>'http://localhost:8080/testing.php','post'=>array('post_var'=>'a')),
    array('url'=>'http://localhost:8080/testing.php','post'=>array('post_var'=>'b')),
    array('url'=>'http://localhost:8080/testing.php','post'=>array('post_var'=>'c')),
);
$curl_result = curl_multi($request);

/*
Array
(
    [0] => a
    [1] => b
    [2] => c
)
*/
echo '<pre>'.print_r($curl_result, true).'</pre>';
?>
于 2013-10-28T15:55:12.957 回答