dongyiluan1718 2015-08-17 09:34
浏览 81
已采纳

循环多卷曲请求PHP的最佳方法

Hi guys I am making a tool which will fetch telephone numbers from the database and make a curl/api request to validate the number and get it's info then update certain fields in the database based from the API response.

So I have a table called phones which has

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

So in my table only the id and number which has values, network and country is null. Which is the reason I will use API that will update those fields depending on the number. However there's a problem, so basically what will happen is I will loop on all those numbers like so:

$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();
}

That will work fine and do my task, but problem is this is very slow when I looped in let's say, 50,000 records, coz before it can send the next curl request, it must wait for the response of the previous one right? Question is how can I make it a 20 request per loop count? Coz the API I'm using supports 20 request per second so I wan't to maximize it.

I know my loop will change coz I need to get 20 records at a time and not repeating the same records again.

  • 写回答

3条回答 默认 最新

  • dqjgf0982 2015-08-17 19:17
    关注

    This is fairly easy with a library like GuzzleHttp. I don't know what your object structure or validation routine looks like, but this example should get you started:

    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 = [];
        }
    }
    

    You can read through the documentation for more details.

    You can also do this with curl_multi_*, but the implementation is much more complex.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥50 永磁型步进电机PID算法
  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 latex怎么处理论文引理引用参考文献
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?