Originariamente inviato da mem
Potresti inserire in un db ogni visitatore che entra nel portale (controlli nel database, se non ce lo inserisci, se ce aggiorni l'ora), dopo 5 minuti se il visitatore se ne è andato, lo cancelli dal database (potresti inserire un controllo dopo 30 secondi, ma faresti appesantire il tuo sito)
Codice PHP:
@$date = date(YmdHi);
//Inserisco nel database i nuovi visitatori o aggiorno l'ora di quelli gia' presenti
$on = mysql_num_rows(mysql_query("SELECT * FROM online WHERE ip='$ip"));
if ($on>0) {
$update = mysql_query("UPDATE online SET date='$date' WHERE ip='$ip'");
} else {
$insert = mysql_query("INSERT INTO online VALUES ('$ip','$date')");
}
//Cancello dal database i dati piu' vecchi di 5 minuti
$old = mysql_query("SELECT * FROM online");
while ($row = mysql_fetch_assoc($old)) {
$ip_db = $row['ip'];
$date_db = $row['date'];
if ($date_db<($date-5)) {
$delete = mysql_query("DELETE FROM online WHERE ip='$ip_db'");
}
}
Sarebbe anche il caso di ottimizzare le query qualche volta...ad esempio:
codice:
//Inserisco nel database i nuovi visitatori o aggiorno l'ora di quelli gia' presenti
$on = mysql_num_rows(mysql_query("SELECT * FROM online WHERE ip='$ip"));
if ($on>0) {
$update = mysql_query("UPDATE online SET date='$date' WHERE ip='$ip'");
} else {
$insert = mysql_query("INSERT INTO online VALUES ('$ip','$date')");
}
lo sostituirei con una REPLACE dato che IP (volendo seguire il tuo scheda), siccome unico, lo imposterei chiave primaria o unique e quindi basterebbe un:
codice:
REPLACE INTO online (ip, date) VALUES( '$ip', NOW() );
in modo da evitare anche la query SELECT.
Poi abolirei quel WHILE xkè è un po inutile...basta costruire una query un po migliore e sostituire:
codice:
//Cancello dal database i dati piu' vecchi di 5 minuti
$old = mysql_query("SELECT * FROM online");
while ($row = mysql_fetch_assoc($old)) {
$ip_db = $row['ip'];
$date_db = $row['date'];
if ($date_db<($date-5)) {
$delete = mysql_query("DELETE FROM online WHERE ip='$ip_db'");
}
}
con un più rapido e pulito:
codice:
DELETE FROM online WHERE (data + INTERVAL 5 MINUTE) < NOW()
Ovviamente tutto questo impostando il campo DATE di tipo TIMESTAMP...
Così in definitiva il codice risultante sarebbe:
codice:
$ip = $_SERVER['REMOTE_ADDR'];
mysql_query("REPLACE INTO online (ip, date) VALUES( '$ip', NOW() );");
mysql_query("DELETE FROM online WHERE (data + INTERVAL 5 MINUTE) < NOW()");
Se analizziamo la differenza è molto grande in termini di spreco...supponendo che nella tabella "online" ci siano 1000 tuple (righe) tutte più vecchie di 5 minuti l'algoritmo proposto prima faceva: 1004 query al database ed un ciclo while da 1000 iterazioni, mentre quello che ho proposto io fa 2 query al database e nessun ciclo while.
Ragazzi ottimizziamo quando si può...in questo modo magari uno si può anche permettere di fare ogni minuto...tanto la query la deve fare le stesso ogni volta che qualcuno carica una pagina...