Så här löste jag det för nu, med hjälp av en fil.
Procedur
- Hämta klientens IP och hasha den (för att förhindra filläsning).
- Öppna IP-filen och skanna varje rad
- Jämför tiden för den aktuella posten med den aktuella tiden
- Om skillnaden är större än inställd timeout, gå till 5., annars 7.
- Om IP matchar klient, skapa uppdaterad post, annars
- släpp post.
- Om IP matchar klienten, ange ett felmeddelande, annars kopiera posten.
Exempelkod
<?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);
?>
Anmärkningar
Nya användare
Om IP-hash inte matchar någon post skapas en ny post. Observera:Åtkomst kan misslyckas om du inte har rättigheter att göra det.
Minne
Om du förväntar dig mycket trafik, byt till en databaslösning som detta alla tillsammans.
Redundant kod
"Men minxomat", kan du säga, "nu går varje klient igenom hela filen!". Ja, verkligen, och det är så jag vill ha det för min lösning. På så sätt är varje klient ansvarig för städningen av hela filen. Trots det hålls prestandapåverkan låg, för om varje klient städar kommer filstorleken att hållas på ett absolut minimum. Ändra detta om det här sättet inte fungerar för dig.