Проверка дубликатов электронной почты в данных ответа API
Я работаю над небольшим внутренним приложением, которое работает с внешним API для целей обеспечения.
Код по существу состоит из серии форм, в которые пользователь вводит данные, которые затем отправляются в API для регистрации новых клиентов.
Это довольно линейный процесс, который я попытаюсь объяснить:
- Создание контакта: основная информация о клиенте (электронная почта, адрес ...).
- Создание клиента: более подробная информация, для создания клиента он должен
contactId
принадлежать именно этому клиенту. - Создание подписчика: информация, связывающая клиента с полученной услугой. Предыдущий шаг должен быть выполнен и
customerId
должен существовать. - Создание службы: содержит дополнительную информацию о службе. И снова,
suscriberId
чтобы связать сервис , необходимо наличие .
Я справился с более или менее быстрым процессом с несколькими настройками здесь и там, но первый шаг (Контакт) имеет метод, который я не могу улучшить, что, в свою очередь, приводит к тому, что этот процесс занимает около минуты. !
Как и весь процесс, описанный ранее, создание каждого из них также очень линейно.
В документации по API указано, что результаты любого GET должны быть разбиты на страницы максимум до 10 записей, но после этого время еще больше увеличивается в течение минуты. Ручные эксперименты показали, что наилучшее соотношение составляет около 500 записей на страницу или, в некоторых случаях, даже полное количество записей оказалось самым быстрым способом, а не 10 на 10.
Поскольку контактный адрес электронной почты нельзя дублировать, первое, что нужно сделать, это проверить адрес электронной почты, указанный в форме, и сравнить его со всеми уже существующими сохраненными сообщениями электронной почты.
Чтобы предоставить $page
и $entries
для вызова API, я должен сначала получить общее количество контактов. Этот номер появляется при вызове API для получения контактов. Итак, первый метод, который я использую:
function fetchTotalContacts($uri, $auth){
$ch = curl_init(); $options = array(
CURLOPT_RETURNTRANSFER => true,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_URL => $uri.'?page=1&rows=1', CURLOPT_HTTPHEADER => array('Content-Type: application/json', 'Authorization: $auth')
);
curl_setopt_array($ch, $options);
$response = curl_exec($ch);
$response = json_decode($response, true);
$totalContacts = $response['total_count'];
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code != 200) { echo "Error en fetchTotalContacts() - Código: $http_code | ";
}
curl_close($ch); return $totalContacts;
}
Теперь, имея $totalContacts
, я могу продолжить и поискать, было ли электронное письмо уже зарегистрировано, и это шаг, который, как я подозреваю, отвечает за высокое время выполнения. Этот метод ищет контакты и их электронные письма, если не находит совпадений, приступает к созданию контакта с предоставленными данными.
function checkDuplicatedEmail($uri, $totalContacts, $contactEmailArray, $auth, $contactEmail, $dataContact){ $ch = curl_init();
$options = array( CURLOPT_RETURNTRANSFER => true, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_URL => $uri.'?page=1&rows='.$totalContacts, CURLOPT_HTTPHEADER => array('Content-Type: application/json', 'Authorization: $auth')
);
curl_setopt_array($ch, $options);
$customers = curl_exec($ch);
$customers = json_decode($customers, true);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($http_code != 200) { echo "Error en checkDuplicatedEmail() - Código: $http_code | ";
}
curl_close($ch); /* foreach ($customers['_embedded']['ngcp:customercontacts'] as $customer) { $email = $customer['email']; array_push($contactEmailArray, $email); } if (in_array($contactEmail, $contactEmailArray)) { echo('El email utilizado ya ha sido registrado en la base de datos'); die(); }else{ $contactCreated = createContact($uri, $dataContact);
return $contactCreated; } */ $repeated = 0;
for ($i=0; $i < $totalContacts ; $i++) {
if ($contactEmail == $customer["_embedded"]["ngcp:customercontacts"][$i]["email"]) { $repeated += 1;
}
}
if ($repeated > 0) { die(echo('El email utilizado ya ha sido registrado en la base de datos')); }else{ $contactCreated = createContact($uri, $dataContact, $auth); return $contactCreated;
}
}
Как видите, это самые быстрые варианты, которые я нашел, и в обоих случаях весь процесс занимает 40 секунд, что все еще слишком много.
Ответ для - это код успеха (400, 201 ..), поэтому, когда я хочу перейти к следующему шагу, мне снова нужно поискать все контакты, чтобы найти тот, который я только что создал, и получить идентификатор. К счастью, здесь я могу просто перейти к последним 20 контактам (не к последнему напрямую, чтобы его можно было использовать одновременно без проблем) и искать там, это делает его очень быстрым, но для электронной почты такого пропуска нет, все записи необходимо проанализировать.createContact($uri, $dataContact, $auth);
Я не знаю, как сократить здесь время, остальная часть кода состоит из выборки contactId
и создания клиента, поэтому там не так много работы, как сейчас.
Если кто-то из вас сочтет необходимым просмотреть остальную часть страницы, я обновлю сообщение.
В качестве последнего напоминания я вручную пробовал использовать разные конфигурации страниц и записей, и для этой страницы был самым быстрым 1 page - All entries
. Я также попытался взять цикл for / each вне метода, но безрезультатно.
Ответы
for
Цикл не будет узким местом в цикле, но то , что кажется очевидным для меня является то , что вы не выигрываете от подсчета выше $repeated = 1
. Это означает, что вам не нужна переменная счетчика, вам действительно нужно событие разрыва цикла - в этом случае die()
. К вашему сведению, die()
напечатайте текст в своем первом параметре, поэтому использование echo
является избыточным.
for ($i=0; $i < $totalContacts; ++$i) { if ($contactEmail == $customer["_embedded"]["ngcp:customercontacts"][$i]["email"]) {
die('El email utilizado ya ha sido registrado en la base de datos');
}
}
return createContact($uri, $dataContact, $auth);
Или другой способ, который, как я предполагаю, будет медленнее (потому что array_column()
будут собирать все электронные письма), - это функциональный дизайн:
if (in_array($contactEmail, array_column($customer["_embedded"]["ngcp:customercontacts"], "email"))) { die('El email utilizado ya ha sido registrado en la base de datos'); } return createContact($uri, $dataContact, $auth);