sql >> データベース >  >> RDS >> Mysql

IPベースのクールダウン期間を提供するポータブルな方法は?

    これが私が今のところファイルを使ってそれを解決した方法です。

    手順

    1. クライアントIPを取得してハッシュします(ファイルの読み取りを防ぐため)。
    2. IPファイルを開き、各行をスキャンします
    3. 現在のレコードの時刻を現在の時刻と比較します
    4. 差が設定されたタイムアウトよりも大きい場合は5に進み、それ以外の場合は7に進みます。
    5. IPがクライアントと一致する場合は、更新されたレコードを作成します。それ以外の場合は
    6. ドロップレコード。
    7. IPがクライアントと一致する場合は失敗メッセージを提供し、そうでない場合はレコードをコピーします。

    サンプルコード

    <?php
    
    $sIPHash    = md5($_SERVER[REMOTE_ADDR]);
    $iSecDelay  = 10;
    $sPath      = "bucket.cache";
    $bReqAllow  = false;
    $iWait      = -1;
    $sContent   = "";
    
    if ($nFileHandle = fopen($sPath, "c+")) {
        flock($nFileHandle, LOCK_EX);
        $iCurLine = 0;
        while (($sCurLine = fgets($nFileHandle, 4096)) !== FALSE) {
            $iCurLine++;
            $bIsIPRec = strpos($sCurLine, $sIPHash);
            $iLastReq = strtok($sCurLine, '|');
            // this record expired anyway:
            if ( (time() - $iLastReq) > $iSecDelay ) {
                // is it also our IP?
                if ($bIsIPRec !== FALSE) {
                    $sContent .= time()."|".$sIPHash.PHP_EOL;
                    $bReqAllow = true;
                }
            } else {
                if ($bIsIPRec !== FALSE) $iWait = ($iSecDelay-(time()-$iLastReq));
                $sContent .= $sCurLine.PHP_EOL;
            }
        }
    }
    
    if ($iWait == -1 && $bReqAllow == false) {
        // no record yet, create one
        $sContent .= time()."|".$sIPHash.PHP_EOL;
        echo "Request from new user successful!";
    } elseif ($bReqAllow == true) {
        echo "Request from old user successful!";
    } else {
        echo "Request failed! Wait " . $iWait . " seconds!";
    }
    
    ftruncate($nFileHandle, 0);
    rewind($nFileHandle);
    fwrite($nFileHandle, $sContent);
    flock($nFileHandle, LOCK_UN);
    fclose($nFileHandle);
    ?>
    

    備考

    新規ユーザー

    IPハッシュがどのレコードとも一致しない場合、新しいレコードが作成されます。重要:アクセスする権限がない場合、アクセスが失敗する可能性があります。

    メモリ

    多くのトラフィックが予想される場合は、これ すべて一緒に。

    冗長コード

    「しかし、minxomat」は、「各クライアントがファイル全体をループするようになりました!」と言うかもしれません。はい、確かに、それが私のソリューションに必要な方法です。このように、すべてのクライアントがファイル全体のクリーンアップを担当します。それでも、すべてのクライアントがクリーニングを実行している場合、ファイルサイズは最小限に抑えられるため、パフォーマンスへの影響は低く抑えられます。この方法でうまくいかない場合は、これを変更してください。




    1. 一般的なエラー:キー制約を作成するときの1005-Laravel

    2. mysql_queryが何かを返したかどうかを確認する

    3. 2パーセントのmysqlLIKE

    4. 列名のパラメーターを使用して順序付け