กำลังตรวจสอบอีเมลที่ซ้ำกันในข้อมูลการตอบกลับ api

Aug 20 2020

ฉันกำลังทำงานกับแอปภายในขนาดเล็กที่ทำงานร่วมกับ API ภายนอกเพื่อวัตถุประสงค์ในการจัดเตรียม

โดยพื้นฐานแล้วโค้ดประกอบด้วยชุดฟอร์มที่ผู้ใช้ป้อนข้อมูลจากนั้นข้อมูลนี้จะถูกส่งไปยัง API เพื่อลงทะเบียนลูกค้าใหม่

นี่เป็นกระบวนการเชิงเส้นค่อนข้างมากฉันจะพยายามอธิบาย:

  1. การสร้างผู้ติดต่อ: ข้อมูลลูกค้าพื้นฐาน (อีเมลที่อยู่ ... )
  2. การสร้างลูกค้า: ข้อมูลขั้นสูงเพิ่มเติมสำหรับการสร้างลูกค้าจะต้องเป็นcontactIdของลูกค้ารายนี้
  3. การสร้างสมาชิก: ข้อมูลที่เชื่อมโยงลูกค้ากับบริการที่ได้รับ ขั้นตอนก่อนหน้านี้จะต้องเสร็จสิ้นและcustomerIdต้องมีอยู่
  4. การสร้างบริการ: ใช้ข้อมูลขั้นสูงเกี่ยวกับบริการ 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 loop นอกเมธอดแล้วก็ไม่เกิดประโยชน์

คำตอบ

2 mickmackusa Aug 20 2020 at 20:27

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);