API応答データで重複するメールをチェックしています

Aug 20 2020

私はプロビジョニングの目的で外部APIに沿って動作する小さな内部アプリに取り組んでいます。

コードは基本的に、ユーザーがデータを入力する一連のフォームで構成され、このデータはAPIに送信されて新しい顧客を登録します。

これは、私が説明しようとするかなり直線的なプロセスです。

  1. 連絡先の作成:基本的な顧客情報(メールアドレス、住所など)。
  2. 顧客の作成:より高度な情報。顧客を作成するcontactIdには、この顧客の所有物が存在する必要があります。
  3. 加入者の作成:顧客を取得したサービスにリンクする情報。前のステップを完了し、customerId存在する必要があります。
  4. サービスの作成:サービスに関する高度な情報が少し続きます。ここでも、suscriberIdサービスをリンクするためにニーズが存在する必要があります。

私はあちこちでいくつかの調整を加えて多かれ少なかれ迅速なプロセスを管理しましたが、最初のステップ(連絡先)には改善できないように見える方法があり、その結果、このプロセスには最大1分かかります!!

前述のプロセス全体と同様に、これらのそれぞれの作成も非常に直線的です。

APIドキュメントには、GETの結果を最大10エントリまでページ分割する必要があると記載されていますが、これに従うと、1分間の時間がさらに長くなります。手動の実験では、最適な比率は1ページあたり約500エントリであることが示されました。場合によっては、エントリの総数でさえ、10 x10ではなく最速の方法であることが証明されました。

連絡先の電子メールは複製できないため、最初に行うことの1つは、フォームで提供された電子メールを確認し、保存されている既存のすべての電子メールと比較することです。

$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 ..)であるため、次の手順に進みたい場合は、もう一度、すべての連絡先を検索して、作成したばかりの連絡先を見つけ、IDを取得する必要があります。幸いなことに、ここでは最後の20件の連絡先(最後の連絡先ではなく、直接問題なく同時に使用できる)にスキップしてそこで検索することができます。これにより、非常に迅速になりますが、メールの場合、そのようなスキップはなく、すべてのエントリがあります。分析する必要があります。createContact($uri, $dataContact, $auth);

ここで時間を削除する方法がわかりません。残りのコードは、をフェッチしcontactIdて顧客を作成することで構成されているため、現在のようにそこで行うことはあまりありません。

ページの残りの部分を表示する必要があると思われる場合は、投稿を更新します。

最後に、ページとエントリのさまざまな構成を手動で試しましたが、このページでは最速でした1 page - All entries。また、for / eachループをメソッドの外に出してみましたが、役に立ちませんでした。

回答

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