So habe ich es vorerst mit einer Datei gelöst.
Verfahren
- Client-IP abrufen und hashen (um das Auslesen der Datei zu verhindern).
- IP-Datei öffnen und jede Zeile scannen
- Vergleichen Sie die Zeit des aktuellen Datensatzes mit der aktuellen Zeit
- Wenn die Differenz größer als das eingestellte Timeout ist, gehe zu 5., sonst 7.
- Wenn die IP mit dem Client übereinstimmt, erstellen Sie einen aktualisierten Datensatz, sonst
- Aufzeichnung löschen.
- Wenn die IP mit dem Client übereinstimmt, geben Sie eine Fehlermeldung ein, andernfalls kopieren Sie den Datensatz.
Beispielcode
<?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);
?>
Bemerkungen
Neue Nutzer
Wenn der IP-Hash mit keinem Datensatz übereinstimmt, wird ein neuer Datensatz erstellt. Achtung:Der Zugriff kann fehlschlagen, wenn Sie nicht über die entsprechenden Rechte verfügen.
Erinnerung
Wenn Sie viel Verkehr erwarten, wechseln Sie zu einer Datenbanklösung wie dies alle zusammen.
Redundanter Code
„Aber Minxomat“, könnte man sagen, „jeder Client durchläuft jetzt die ganze Datei!“. Ja, in der Tat, und so will ich es auch für meine Lösung. Auf diese Weise ist jeder Client für die Bereinigung der gesamten Datei verantwortlich. Trotzdem wird die Auswirkung auf die Leistung gering gehalten, da die Dateigröße auf dem absoluten Minimum gehalten wird, wenn jeder Client bereinigt. Ändern Sie dies, wenn dieser Weg für Sie nicht funktioniert.