W ten sposób na razie rozwiązałem to, używając pliku.
Procedura
- Uzyskaj adres IP klienta i zaszyfruj go (aby zapobiec odczytaniu pliku).
- Otwórz plik IP i zeskanuj każdą linię
- Porównaj czas bieżącego rekordu z czasem bieżącym
- Jeśli różnica jest większa niż ustawiony limit czasu, przejdź do 5., w przeciwnym razie 7.
- Jeśli adres IP pasuje do klienta, utwórz zaktualizowany rekord, w przeciwnym razie
- upuść rekord.
- Jeśli adres IP pasuje do klienta, podaj komunikat o błędzie, w przeciwnym razie skopiuj rekord.
Przykładowy kod
<?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);
?>
Uwagi
Nowi użytkownicy
Jeśli hash IP nie pasuje do żadnego rekordu, tworzony jest nowy rekord. Uwaga:dostęp może się nie powieść, jeśli nie masz do tego uprawnień.
Pamięć
Jeśli spodziewasz się dużego ruchu, przełącz się na rozwiązanie bazodanowe, takie jak to wszystko razem.
Zbędny kod
„Ale minxomat”, można powiedzieć, „teraz każdy klient przegląda cały plik!”. Tak, rzeczywiście i właśnie tego chcę dla mojego rozwiązania. W ten sposób każdy klient jest odpowiedzialny za oczyszczenie całego pliku. Mimo to wpływ na wydajność jest utrzymywany na niskim poziomie, ponieważ jeśli każdy klient czyści, rozmiar pliku będzie utrzymywany na absolutnym minimum. Zmień to, jeśli ten sposób nie działa dla Ciebie.