Hello Mac,
Du hast Recht, 100% ist das nicht. Die Kombination IP + Permalink sollte aber für mich ausreichen. (Das Ganz soll eine Art "Gefällt mir" Button für Beiträge werden, wo darunter die Anzahl der Klicks steht.)
Ich habe Dir nochmal eine Lösung gebastelt, die mit einem serialisierten Array arbeitet. Du kannst sie ja mal ausprobieren (Habe ich noch nicht) und den Code sicherlich auch noch etwas zusammenfassen an einigen Stellen.
Du siehst, dass diese Lösung ganz ohne explizite Schleifen auskommt. Die sind alle versteckt in den PHP-Funktionen und -Funktionalitäten.
<?php ### linkcounter.php ###
$filename = '.ht_clickcounter.txt';
Zur Installation Kommentarzeichen entfernen
touch($filename)
define('IP_BLOCKINGTIME', 3600); ## Blockintime 1 Hour
----------------------------------------------------
$ip = $_SERVER['REMOTE_ADDR'];
$link = $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'];
ggf. noch ergänzen um den Query-String
/*
if (isset($_SERVER['QUERY_STRING']))
{
$link = $_SERVER['HTTP_HOST'] . $_SERVER['SCRIPT_NAME'] .'?'. $_SERVER['QUERY_STRING'];
}
*/
eventuell X_FORWARDED_FOR berücksichtigen
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']))
{
$ip .= ';' . $_SERVER['HTTP_X_FORWARDED_FOR'];
}
$time = time();
----------------------------------------------------
Aufbau eines Records, $link ist Index
#$_linklist = array();
#$_linklist[$link] = array();
#$_linklist[$link][$ip] = array();
#$_linklist[$link][$ip]['lasttime'] = 0;
#$_linklist[$link][$ip]['clicks'] = 0;
Daten holen
$fh = @fopen($filename, 'rb+');
if (!$fh) exit;
if (!flock($fh, LOCK_EX)) exit;
$stream = fread($fh, filesize($filename));
$_linklist = unserialize($stream);
unset($data);
if (!is_array($_linklist)) exit;
Ist der Link bereits in der Liste?
if (isset ($_linklist['$link']))
{
## Ist der Link schon von der IP aufgerufen worden?
if (isset ($_linklist[$link][$ip]))
{
## Wie lange ist es her, dass der Link aufgerufen wurde?
if ($time - $_linklist[$link][$ip]['lasttime'] > IP_BLOCKINGTIME )
{
## Aufrufzähler hochzählen und Aufrufzeit nachtriggern
$_linklist[$link][$ip]['clicks'] ++;
$_linklist[$link][$ip]['lasttime'] = $time;
}
else
{
## Nur Letzte Aufrufzeit nachtriggern
$_linklist[$link][$ip]['lasttime'] = $time;
}
}
else
{
## Neue IP für den Link eintragen,
## letzte Aufrufzeit setzen und
## Klickzähler hochsetzen
$_linklist[$link][$ip] = array();
$_linklist[$link][$ip]['lasttime'] = $time;
$_linklist[$link][$ip]['clicks'] = 1;
}
}
else
{
## Datensatz für Link komplett neu anlegen
$_linklist[$link] = array();
$_linklist[$link][$ip] = array();
$_linklist[$link][$ip]['lasttime'] = $time;
$_linklist[$link][$ip]['clicks'] = 1;
}
Array serialaisieren
$stream = serialize ($_linklist);
Daten wegschreiben
fseek($fh, 0, SEEK_SET);
fwrite($fh, $stream);
ftruncate($fh, strlen($stream));
fclose($fh);
?>
Wenn Du es zum Laufen gebracht hast und verstanden hast, was wie gedacht ist, dann kannst Du daraus auch eine Funktion machen, die dann an passender Stelle aufgerufen werden kann. Die "exit"-Anweisungen solltest Du dann gegen "return" austauschen. Dann bekommt das Ganze so langsam Struktur.
Dein Lösungsweg ist allerdings dann besser geeignet, wenn die gesammelten Datenmengen groß werden sollen, die Datei also nicht vollständig in den Speicher passt.
Guten Rutsch
und liebe Grüße aus dem schönen Oberharz
Tom vom Berg
Ich gehe jetzt Silvester feiern