【问题标题】:Best approach for Looped Multi-Curl Request PHP循环多卷曲请求 PHP 的最佳方法
【发布时间】:2015-08-17 09:34:35
【问题描述】:

大家好,我正在制作一个工具,该工具将从数据库中获取电话号码并发出 curl/api 请求以验证号码并获取其信息,然后根据 API 响应更新数据库中的某些字段。

所以我有一个名为phones 的表

->id
->number
->network
->country

所以在我的表中只有 idnumber 有值,networkcountry 为空。这就是我将使用 API 来根据数字更新这些字段的原因。但是有一个问题,所以基本上会发生什么我会像这样循环所有这些数字:

$phone = Phone::all();
foreach ($phone as $key => $value) 
{
  // Call the API that will get the details in the current number
  // and update the details in the table for the current number 

  /** Some code for API Call **/

  //Update Script
  $update = Phone::find($value->id);
  $update->network = $network;
  $update->country = $country;
  $update->country_prefix = $country_prefix;
  $update->status = $status;
  $update->remarks = $remarks;
  $update->save();
}

这可以很好地完成我的任务,但问题是当我循环输入时这非常慢,比如说 50,000 条记录,因为在它可以发送下一个 curl 请求之前,它必须等待前一个的响应对?问题是如何使每个循环计数为 20 个请求?因为我使用的 API 支持每秒 20 个请求,所以我不想最大化它。

我知道我的循环会改变,因为我需要一次获取 20 条记录,并且不再重复相同的记录。

【问题讨论】:

    标签: php multithreading curl


    【解决方案1】:

    使用像 GuzzleHttp 这样的库非常容易。我不知道您的对象结构或验证例程是什么样的,但这个示例应该可以帮助您入门:

    use GuzzleHttp\Client;
    use GuzzleHttp\Promise;
    
    $client = new Client(['base_uri' => 'http://example.com/api/']);
    
    $updates = [];
    $phone = Phone::all();
    foreach ($phone as $key => $value)
    {
    
        $update = Phone::find($value->id);
        $update->network = $network;
        $update->country = $country;
        $update->country_prefix = $country_prefix;
        $update->status = $status;
        $update->remarks = $remarks;
    
        // Load updates into array for processing
        $updates[$update->id] = $update;
    
        if (count($updates) == 20) {
    
            // Setting up the async requests
            $promises = [];
    
            foreach ($updates as $u) {
                // This is posting to http://example.com/api/phone, appending to the 'base_uri' above.
                // This will send a json body, but you can change the format as necessary
                $promises[$u->id] = $client->postAsync('/phone', ['json' => ['phone' => $u->number]]);
            }
    
            // Waits for the requests to complete
            $results = Promise\unwrap($promises);
    
            // Saves each number with a 200 response
            foreach ($results as $id => $result) {
                if ($result->getStatusCode() == 200) {
                    $updates[$id]->save();
                }
            }
    
            // Clear processed records from array
            $updates = [];
        }
    }
    

    您可以阅读documentation 了解更多详情。

    您也可以使用curl_multi_* 执行此操作,但实现要复杂得多。

    【讨论】:

      【解决方案2】:

      如果您使用的 API 每次调用可以处理多个号码,那么您可以批量请求手机号码的详细信息,而不是一一发送。 批量请求详细信息将减少请求/响应周期的成本。

      【讨论】:

      • 是的,这就是我想要做的。但我不知道从哪里开始
      • 没问题,这个sn-p会帮你入手,
      • $phone = Phone::all(); foreach ($phone as $key => $value) { // 调用将获取当前号码详细信息的 API // 并更新当前号码表中的详细信息 /** API 调用的一些代码 ** //更新脚本 $update = Phone::find($value->id); $更新->网络= $网络; $更新->国家= $国家; $update->country_prefix = $country_prefix; $更新->状态 = $状态; $update->remarks = $remarks; $更新->保存(); }
      【解决方案3】:
      $phone = Phone::all();
      $counter=0;
      $some_threshold=100; 
      $requestArray = array();
      foreach ($phone as $key => $value) 
      {
          $requestArray[] = $value;
          if($counter >= $some_threshold)
          {
                // Call the API that will get the details in the  numbers in $requestArray 
                foreach($response as $result)
                {
                    $update = Phone::find($value->id);
                    $update->network = $network;
                    $update->country = $country;
                    $update->country_prefix = $country_prefix;
                    $update->status = $status;
                    $update->remarks = $remarks;
                    $update->save();
                }
               $counter=0;
               $requestArray = array();
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2011-04-23
        • 2011-09-16
        • 2014-08-21
        • 2016-08-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-12-16
        • 2023-03-08
        相关资源
        最近更新 更多