2015-08-17 5 views
1

Привет, ребята, я делаю инструмент, который будет извлекать номера телефонов из базы данных и делать запрос curl/api для проверки номера и получения его информации, а затем обновлять определенные поля в базе данных на основе из ответа API.Лучший подход для Looped Multi-Curl Request PHP

Поэтому у меня есть таблица под названием phones, который имеет

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

Так в моей таблице только id и number, который имеет значения, network и country является нулевым. Именно по этой причине я буду использовать 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 записей, прежде чем он сможет отправить следующий запрос на завиток, он должен дождаться ответа предыдущего права? Вопрос в том, как я могу сделать это 20 запросов на количество циклов? Coz API, который я использую, поддерживает 20 запросов в секунду, поэтому я не хочу его максимизировать.

Я знаю, что моя петля изменится. Мне нужно получить 20 записей за раз, а не повторять одни и те же записи.

ответ

0

Это довольно легко с библиотекой, например, 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_*, но реализация намного сложнее.

0

Если API, который вы используете, может обрабатывать более одного номера за звонок, вы можете запросить детали мобильного номера оптом, а не отправлять по одному. Массовый запрос на детали уменьшит стоимость в цикле запроса/ответа.

+0

Да, что я хочу делать. Но я не знаю с чего начать – jackhammer013

+0

Нет проблем, этот фрагмент поможет вам с нуля, – user5212481

+0

$ phone = Phone :: all(); Еогеасп ($ телефон, как $ ключ => $ значение) { // Вызов API, который будет получать подробную информацию в текущий номер // и обновить данные в таблице для текущего номера /** Некоторые код для API-вызова **/ // Обновление сценария $ update = Phone :: find ($ value-> id); $ update-> network = $ network; $ update-> страна = $ страна; $ update-> country_prefix = $ country_prefix; $ update-> status = $ status; $ update-> примечания = $ замечания; $ update-> save(); } – user5212481

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