Überprüfen der API-Antwortdaten auf doppelte E-Mails
Ich arbeite an einer kleinen internen App, die zu Bereitstellungszwecken entlang einer externen API arbeitet.
Der Code besteht im Wesentlichen aus einer Reihe von Formularen, in denen der Benutzer Daten eingibt. Diese Daten werden dann an die API gesendet, um neue Kunden zu registrieren.
Dies ist ein ziemlich linearer Prozess, den ich zu erklären versuchen werde:
- Kontakterstellung: Grundlegende Kundeninformationen (E-Mail, Adresse ...).
- Kundenerstellung: Erweiterte Informationen, damit ein Kunde erstellt werden kann, muss eine
contactIdZugehörigkeit zu diesem Kunden vorhanden sein. - Abonnentenerstellung: Informationen, die den Kunden mit dem erworbenen Service verknüpfen. Der vorherige Schritt muss abgeschlossen sein und ein
customerIdMuss vorhanden sein. - Serviceerstellung: Enthält einige erweiterte Informationen zum Service. Es muss wieder ein
suscriberIdvorhanden sein, um den Dienst zu verknüpfen.
Ich habe hier und da einen mehr oder weniger schnellen Prozess mit ein paar Änderungen geschafft, aber der erste Schritt (Kontakt) hat eine Methode, die ich scheinbar nicht verbessern kann, was wiederum dazu führt, dass dieser Prozess bis zu einer vollen Minute dauert !
Wie der gesamte zuvor beschriebene Prozess ist auch die Erstellung jedes dieser Prozesse sehr linear.
In der API-Dokumentation heißt es, dass die Ergebnisse eines GET auf maximal 10 Einträge paginiert werden sollten. Im Anschluss daran erhöht sich die Zeit im Laufe der Minute jedoch weiter. Manuelle Experimente zeigten, dass das beste Verhältnis etwa 500 Einträge pro Seite beträgt, oder in einigen Fällen erwies sich sogar die Gesamtzahl der Einträge als der schnellste Weg, anstatt 10 mal 10 zu gehen.
Da die Kontakt-E-Mail nicht dupliziert werden kann, müssen Sie zunächst nach der im Formular angegebenen E-Mail suchen und sie mit allen bereits vorhandenen gespeicherten E-Mails vergleichen.
Um den $pageund $entriesfür den API-Aufruf bereitzustellen , muss ich zuerst die Gesamtzahl der Kontakte abrufen. Diese Nummer wird angezeigt, wenn die API aufgerufen wird, um die Kontakte abzurufen. Die erste Methode, die ich benutze, ist:
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;
}
Jetzt $totalContactskann ich fortfahren und suchen, ob die E-Mail bereits registriert wurde. Dies ist der Schritt, von dem ich vermute, dass er für die hohe Ausführungszeit verantwortlich ist. Diese Methode durchsucht die Kontakte und ihre E-Mails. Wenn kein Zufall festgestellt wird, wird der Kontakt mit den angegebenen Daten erstellt.
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;
}
}
Wie Sie sehen können, sind dies die schnellsten Optionen, die ich gefunden habe. Beide dauern den gesamten Prozess 40 Sekunden, was noch zu viel ist.
Die Antwort für ist ein Erfolgscode (400, 201 ..). Wenn ich also mit dem nächsten Schritt fortfahren möchte, muss ich erneut alle Kontakte durchsuchen, um den gerade erstellten zu finden und die ID zu erhalten. Glücklicherweise kann ich hier einfach zu den letzten 20 Kontakten springen (nicht zu den letzten direkt, damit sie ohne Probleme gleichzeitig verwendet werden können) und dort suchen. Dies macht es sehr schnell, aber für die E-Mail gibt es keinen solchen Sprung, alle Einträge muss analysiert werden.createContact($uri, $dataContact, $auth);
Ich weiß nicht, wie ich die Zeit hier verlieren soll. Der Rest des Codes besteht darin, den zu holen contactIdund den Kunden zu erstellen, so dass dort nicht viel zu tun ist, wie es jetzt ist.
Wenn einer von Ihnen es für notwendig hält, den Rest der Seite zu sehen, werde ich den Beitrag aktualisieren.
Als letzte Erinnerung habe ich es manuell mit verschiedenen Konfigurationen von Seiten und Einträgen versucht und für diese Seite war die schnellste 1 page - All entries. Ich habe auch versucht, die for / each-Schleife außerhalb der Methode zu verwenden, ohne Erfolg.
Antworten
Die forSchleife wird nicht der Engpass in Ihrer Schleife sein, aber was mir offensichtlich erscheint, ist, dass Sie nicht davon profitieren, höher als zu zählen $repeated = 1. Dies bedeutet, dass Sie keine Zählervariable benötigen, sondern tatsächlich ein Schleifenunterbrechungsereignis - in diesem Fall die(). Zu Ihrer Information die()wird der Text in seinem ersten Parameter gedruckt, sodass die Verwendung echoredundant ist.
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);
Oder ein anderer Weg, von dem ich annehme, dass er langsamer ist (weil array_column()alle E-Mails gesammelt werden), ist dieses funktionale Design:
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);