我正在制作一个工具,它将从数据库中获取电话号码,并使curl/api请求验证该号码并获取其信息,然后根据api响应更新数据库中的某些字段。
我有一个名为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条记录时,速度很慢,因为在它发送下一个curl请求之前,它必须等待前一个请求的响应?问题是我如何使它每循环计数为20个请求?因为我使用的API支持每秒20个请求,所以我不想最大化它。
我知道我的循环将改变,因为我需要一次获得20条记录,而不是再次重复相同的记录
对于像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 = [];
}
}
您可以通读文档了解更多细节。
您也可以对curl_multi_*
执行此操作,但实现要复杂得多。
如果您正在使用的API每次呼叫可以处理多个号码,那么您可以批量请求手机号码的详细信息,而不是逐个发送。批量请求详细信息将减少请求/响应周期中的成本。
$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();
}
}