Sådan løste jeg det for nu ved hjælp af en fil.
Procedure
- Hent klient-IP og hash den (for at forhindre filudlæsning).
- Åbn IP-fil, og scan hver linje
- Sammenlign tiden for den aktuelle registrering med den aktuelle tid
- Hvis forskellen er større end den indstillede timeout, gå til 5., ellers 7.
- Hvis IP matcher klient, skal du oprette en opdateret post, ellers
- slip post.
- Hvis IP matcher klient, angiv fejlmeddelelse, ellers kopier registrering.
Eksempelkode
<?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);
?>
Bemærkninger
Nye brugere
Hvis IP-hashen ikke matcher nogen post, oprettes en ny post. Bemærk:Adgang kan mislykkes, hvis du ikke har rettigheder til at gøre det.
Hukommelse
Hvis du forventer meget trafik, så skift til en databaseløsning som dette alle sammen.
Redundant kode
"Men minxomat", kan du sige, "nu går hver klient gennem hele filen!". Ja, faktisk, og det er sådan, jeg vil have det til min løsning. På denne måde er hver klient ansvarlig for oprydningen af hele filen. Alligevel holdes ydeevnepåvirkningen lav, for hvis hver klient renser, vil filstørrelsen blive holdt på et absolut minimum. Skift dette, hvis denne måde ikke virker for dig.