如何重构这个cURL脚本以利用PHP';s curl_多功能?

如何重构这个cURL脚本以利用PHP';s curl_多功能?,php,curl,curl-multi,Php,Curl,Curl Multi,我在PHP应用程序中使用cURL连接到RESTful API。然而,我最近发现我没有并行化cURL连接,因此执行几个连续的连接会给最终用户带来极大的延迟 我以前没有使用过curl\u multi,在阅读了文档之后,我有点不知所措。如何最好地重构以下代码以利用curl\u multi的并行化 编辑:我忘了提到我公开了这里使用的API。这些是我自己的。因此,如果您愿意,您也可以将这里的帮助合并到GitHub上的代码中,您将被列为贡献者 下面是我在客户端代码中所做的一个示例: // Get 100

我在PHP应用程序中使用cURL连接到RESTful API。然而,我最近发现我没有并行化cURL连接,因此执行几个连续的连接会给最终用户带来极大的延迟

我以前没有使用过
curl\u multi
,在阅读了文档之后,我有点不知所措。如何最好地重构以下代码以利用
curl\u multi
的并行化

编辑:我忘了提到我公开了这里使用的API。这些是我自己的。因此,如果您愿意,您也可以将这里的帮助合并到GitHub上的代码中,您将被列为贡献者

下面是我在客户端代码中所做的一个示例:

 // Get 100 goal recommendations from Directed Edge
  $de = new DirectedEdgeRest();
  $item = "user".$uid;
  $limit = 100;
  $tags = "goal";
  $recommendedGoals = $de->getRecommended($item, $tags, $limit);

  // Get 100 interest recommendations from Directed Edge
  $de = new DirectedEdgeRest();
  $item = "user".$uid;
  $limit = 100;
  $tags = "interest";
  $recommendedInterests = $de->getRecommended($item, $tags, $limit);
下面是来自
directedgerest()的相关函数


在你提问之前,我不知道
curl\u multi
,这是一个非常奇怪的(PHP)接口

看起来好像有一个


我会从这开始。

如果有人感兴趣,下面是我如何重构代码以利用
curl\u multi
。如果这一切看起来很酷,或者你能做得更好,那就请吧

class DirectedEdgeRest
{
  /**
   * Gets multiple simultaneous recommendations from Directed Edge
   * @param array $queryArray Array of the form array(0 => (array('item' => (string) $item, 'tags' => (string) $tags, 'limit' => (int) $limit))
   *
   * @return array Multi-dimensional array containing responses to
   *  queries in the order they were passed in the array
   */
  public function getMultiRecommended($queryArray)
  {
    $targetUrls = array();

    foreach($queryArray as $query) {
      $targeturl = self::buildURL($query['item'], 'recommended', $query['tags'], $query['limit'], 'true');
      $targetUrls[] = $targeturl;
    }

    $responses = self::getMultiCurlResponses($targetUrls);

    $xmlArray = array();

    foreach($responses as $response) {
      $xmlArray[] = self::parseXML($response);      
    }

    $count =  count($xmlArray);

    // Iterate through the XML and place IDs into an array
    for($i = 0; $i < $count; $i++) {            
      foreach($xmlArray[$i]->item->recommended as $recommended) {
        $recommendedResults[$i][] = filter_var($recommended, FILTER_SANITIZE_NUMBER_INT);
      }
    }

    return $recommendedResults;
  }

  /**
   * Returns the cURL responses given multiple target URLs
   * @param array $targetUrls Array of target URLs for cURL
   *
   * @return array cURL Responses
   */
  private function getMultiCurlResponses($targetUrls)
  {
    // Cache the count
    $count = count($targetUrls);

    // Create the multiple cURL handles
    for($i = 0; $i < $count; $i++) {
      $ch[$i] = curl_init($targetUrls[$i]);
      curl_setopt($ch[$i], CURLOPT_POST, FALSE);
      curl_setopt($ch[$i], CURLOPT_SSL_VERIFYPEER, FALSE);
      curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, TRUE);
    }

    // Initialize the multiple cURL handle
    $mh = curl_multi_init();

    // Add the handles to the curl_multi handle
    for($i = 0; $i < $count; $i++) {
      curl_multi_add_handle($mh, $ch[$i]);
    }

    $running=null;
    // Execute the handles
    do {
      curl_multi_exec($mh,$running);
    } while ($running > 0);

    $responses = array();

    // Remove the handles and return the response
    for($i = 0; $i < $count; $i++) {
      curl_multi_remove_handle($mh, $ch[$i]);

      $responses[$i] = curl_multi_getcontent($ch[$i]);
    }

    // Close the multiple cURL handle
    curl_multi_close($mh);

    return $responses;
  }
}

$uid = 3;
$de = new DirectedEdgeRest();
$query['item'] = "user".$uid;
$query['limit'] = 10;
$query['tags'] = "goal";
$queryArray[0] = $query;

$query['tags'] = "question";
$queryArray[1] = $query;


$recommended = $de->getMultiRecommended($queryArray);
echo '<pre>';
var_dump($recommended);

// Outputs...
array(2) {
  [0]=>
  array(10) {
    [0]=>
    string(3) "141"
    [1]=>
    string(2) "64"
    [2]=>
    string(2) "37"
    [3]=>
    string(2) "65"
    [4]=>
    string(2) "63"
    [5]=>
    string(1) "7"
    [6]=>
    string(2) "78"
    [7]=>
    string(1) "9"
    [8]=>
    string(2) "30"
    [9]=>
    string(2) "10"
  }
  [1]=>
  array(10) {
    [0]=>
    string(2) "97"
    [1]=>
    string(3) "125"
    [2]=>
    string(3) "133"
    [3]=>
    string(3) "127"
    [4]=>
    string(3) "101"
    [5]=>
    string(3) "134"
    [6]=>
    string(2) "69"
    [7]=>
    string(2) "80"
    [8]=>
    string(2) "19"
    [9]=>
    string(3) "129"
  }
}
class-directedgerest
{
/**
*从定向边缘获取多个同时建议
*@param array$queryArray数组的形式数组(0=>(数组('item'=>(string)$item,'tags'=>(string)$tags,'limit'=>(int)$limit))
*
*@return array多维数组,包含对
*按查询在数组中传递的顺序进行查询
*/
公共函数getMultiRecommended($queryArray)
{
$targetUrls=array();
foreach($queryArray作为$query){
$targeturl=self::buildURL($query['item'],'recommended',$query['tags'],$query['limit'],'true');
$targetUrls[]=$targeturl;
}
$responses=self::getmulticurresponses($targetUrls);
$xmlArray=array();
foreach($response作为$response){
$xmlArray[]=self::parseXML($response);
}
$count=count($xmlArray);
//遍历XML并将ID放入数组中
对于($i=0;$i<$count;$i++){
foreach($xmlArray[$i]->item->推荐为$recommended){
$recommendedResults[$i][]=filter\u var($recommendedResults,filter\u SANITIZE\u NUMBER\u INT);
}
}
返回$recommendedResults;
}
/**
*返回给定多个目标URL的cURL响应
*@param array$targetUrls cURL的目标URL数组
*
*@returnarray cURL响应
*/
私有函数getMultiCurlResponses($targetUrls)
{
//缓存计数
$count=count($targetUrls);
//创建多个卷曲控制柄
对于($i=0;$i<$count;$i++){
$ch[$i]=curl_init($targetUrls[$i]);
curl_setopt($ch[$i],CURLOPT_POST,FALSE);
curl_setopt($ch[$i],CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch[$i],CURLOPT_RETURNTRANSFER,TRUE);
}
//初始化多重卷曲句柄
$mh=curl_multi_init();
//将控制柄添加到curl\u多控制柄
对于($i=0;$i<$count;$i++){
卷曲多加把手($mh,$ch[$i]);
}
$running=null;
//执行句柄
做{
curl_multi_exec($mh,$running);
}而($running>0);
$responses=array();
//移除句柄并返回响应
对于($i=0;$i<$count;$i++){
卷曲多移除手柄($mh,$ch[$i]);
$responses[$i]=curl_multi_getcontent($ch[$i]);
}
//关闭多重卷曲控制柄
卷曲多重闭合($mh);
返回$responses;
}
}
$uid=3;
$de=新的DirectedgeRest();
$query['item']=“用户”。$uid;
$query['limit']=10;
$query['tags']=“目标”;
$queryArray[0]=$query;
$query['tags']=“问题”;
$queryArray[1]=$query;
$recommended=$de->getMultiRecommended($queryArray);
回声';
var_dump(建议美元);
//输出。。。
阵列(2){
[0]=>
阵列(10){
[0]=>
字符串(3)“141”
[1]=>
字符串(2)“64”
[2]=>
字符串(2)“37”
[3]=>
字符串(2)“65”
[4]=>
字符串(2)“63”
[5]=>
字符串(1)“7”
[6]=>
字符串(2)“78”
[7]=>
字符串(1)“9”
[8]=>
字符串(2)“30”
[9]=>
字符串(2)“10”
}
[1]=>
阵列(10){
[0]=>
字符串(2)“97”
[1]=>
字符串(3)“125”
[2]=>
字符串(3)“133”
[3]=>
字符串(3)“127”
[4]=>
字符串(3)“101”
[5]=>
字符串(3)“134”
[6]=>
字符串(2)“69”
[7]=>
串(2)“80”
[8]=>
字符串(2)“19”
[9]=>
字符串(3)“129”
}
}

谢谢。我现在有了一个非常好、快速的工具。与Memcached一起使用,一切都会变得很有魅力。我添加了一个答案(尽管我接受了你的答案,因为它让我达到了我想要的目标),展示了我是如何重构的。请查看它,让我知道你的想法
// create both cURL resources
$ch1 = curl_init();
$ch2 = curl_init();

// set URL and other appropriate options
curl_setopt($ch1, CURLOPT_URL, "http://www.example.com/");
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/");
curl_setopt($ch2, CURLOPT_HEADER, 0);

//create the multiple cURL handle
$mh = curl_multi_init();

//add the two handles
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);

$running=null;
//execute the handles
do {
    usleep(10000);
    curl_multi_exec($mh,$running);
} while ($running > 0);

//close the handles
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
class DirectedEdgeRest
{
  /**
   * Gets multiple simultaneous recommendations from Directed Edge
   * @param array $queryArray Array of the form array(0 => (array('item' => (string) $item, 'tags' => (string) $tags, 'limit' => (int) $limit))
   *
   * @return array Multi-dimensional array containing responses to
   *  queries in the order they were passed in the array
   */
  public function getMultiRecommended($queryArray)
  {
    $targetUrls = array();

    foreach($queryArray as $query) {
      $targeturl = self::buildURL($query['item'], 'recommended', $query['tags'], $query['limit'], 'true');
      $targetUrls[] = $targeturl;
    }

    $responses = self::getMultiCurlResponses($targetUrls);

    $xmlArray = array();

    foreach($responses as $response) {
      $xmlArray[] = self::parseXML($response);      
    }

    $count =  count($xmlArray);

    // Iterate through the XML and place IDs into an array
    for($i = 0; $i < $count; $i++) {            
      foreach($xmlArray[$i]->item->recommended as $recommended) {
        $recommendedResults[$i][] = filter_var($recommended, FILTER_SANITIZE_NUMBER_INT);
      }
    }

    return $recommendedResults;
  }

  /**
   * Returns the cURL responses given multiple target URLs
   * @param array $targetUrls Array of target URLs for cURL
   *
   * @return array cURL Responses
   */
  private function getMultiCurlResponses($targetUrls)
  {
    // Cache the count
    $count = count($targetUrls);

    // Create the multiple cURL handles
    for($i = 0; $i < $count; $i++) {
      $ch[$i] = curl_init($targetUrls[$i]);
      curl_setopt($ch[$i], CURLOPT_POST, FALSE);
      curl_setopt($ch[$i], CURLOPT_SSL_VERIFYPEER, FALSE);
      curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, TRUE);
    }

    // Initialize the multiple cURL handle
    $mh = curl_multi_init();

    // Add the handles to the curl_multi handle
    for($i = 0; $i < $count; $i++) {
      curl_multi_add_handle($mh, $ch[$i]);
    }

    $running=null;
    // Execute the handles
    do {
      curl_multi_exec($mh,$running);
    } while ($running > 0);

    $responses = array();

    // Remove the handles and return the response
    for($i = 0; $i < $count; $i++) {
      curl_multi_remove_handle($mh, $ch[$i]);

      $responses[$i] = curl_multi_getcontent($ch[$i]);
    }

    // Close the multiple cURL handle
    curl_multi_close($mh);

    return $responses;
  }
}

$uid = 3;
$de = new DirectedEdgeRest();
$query['item'] = "user".$uid;
$query['limit'] = 10;
$query['tags'] = "goal";
$queryArray[0] = $query;

$query['tags'] = "question";
$queryArray[1] = $query;


$recommended = $de->getMultiRecommended($queryArray);
echo '<pre>';
var_dump($recommended);

// Outputs...
array(2) {
  [0]=>
  array(10) {
    [0]=>
    string(3) "141"
    [1]=>
    string(2) "64"
    [2]=>
    string(2) "37"
    [3]=>
    string(2) "65"
    [4]=>
    string(2) "63"
    [5]=>
    string(1) "7"
    [6]=>
    string(2) "78"
    [7]=>
    string(1) "9"
    [8]=>
    string(2) "30"
    [9]=>
    string(2) "10"
  }
  [1]=>
  array(10) {
    [0]=>
    string(2) "97"
    [1]=>
    string(3) "125"
    [2]=>
    string(3) "133"
    [3]=>
    string(3) "127"
    [4]=>
    string(3) "101"
    [5]=>
    string(3) "134"
    [6]=>
    string(2) "69"
    [7]=>
    string(2) "80"
    [8]=>
    string(2) "19"
    [9]=>
    string(3) "129"
  }
}