Du bist hier: StartPHPKlassen › BesucherzählerDieses Snippet kommentieren

<?php
 
/**
 * Besucher-Zähler
 *
 * Der Counter zählt die Besucher (= Aufrufe jeder Seite) in
 * zwei Tabellen: In der großen Tabelle werden alle Aufrufe
 * über den gesamten Zeitraum gesichert (Archiv), in der
 * kleinen Tabelle sind nur die letzten 10.000 Besucher
 * enthalten. Dies ist notwendig, um die aktuelle Statistik
 * (z.B. "Besucher heute" oder "Besucher in dieser Woche")
 * nicht immer auf Basis der auf Dauer riesig werdenden
 * Tabelle erstellen zu müssen (SQL-Performance).
 *
 * Zu jedem Hit wird nur die IP und die Aufrufzeit
 * gespeichert. Mit Hilfe von $cfg['reload_time'] kann (in
 * Sekunden) angegeben werden, ab welchem Abstand einer
 * zweiter Seitenaufruf als neuer Besucher gewertet werden
 * soll.
 */
abstract class Counter
{
    // ===========================================================================
    // SCHNITTSTELLE
    // ===========================================================================
 
 
    /**
     * Diese Methode zählt einen Aufruf von
     * einer $ip. Sie kümmert sich selber um die
     * Ablaufzeit, darum, den Eintrag in beiden
     * Tabellen einzufügen und ggf. auch den Tages-
     * wechsel zu beachten.
     *
     * Da die Methode in der Regel aufgerufen wird,
     * ohne dass ein MySQL-Objekt besteht, nutzt sie
     * die mysql_*-Funktionen von PHP direkt.
     *
     * @param string   $ip             die IP des Besuchers
     * @param resource $sqlConnection  die zu verwendende Datenbank-Verbindung
     */
    public static function countHit($ip,$sqlConnection)
    {
        if(DEBUG) Debug::checkArguments(__METHOD__,"sr",$ip,$sqlConnection);
 
        // In der Regel ist beim Aufruf von countHit
        // noch keine Registry vorhanden, daher würde
        // ein Registry::get("cfg") nichts bringen.
        global $cfg;
 
        $_now       = time();
        $_today     = mktime(0,0,0,date('n'),date('j'),date('Y'));
        $now_mysql  = strftime("%Y-%m-%d %H:%M:%S");
        $max        = strftime("%Y-%m-%d %H:%M:%S",time()-4*ONE_DAY);
 
        // Prüfen, ob diese IP bereits in der DB vorhanden ist.
        $result = mysql_query("SELECT UNIX_TIMESTAMP(hit) AS hit FROM ".TBL_COUNTER_RECENT." WHERE hit >= '$max' AND ip = '$ip' ORDER BY hit DESC",$sqlConnection);
 
        // Möglichkeit 1: nicht gefunden -> neuer Besucher
        // Möglichkeit 2: gefunden, aber alt -> neuer Besucher
        // Möglichkeit 3: gefunden, aktuell -> kein neuer Besucher
 
        // Und dann müssen wir noch unterscheiden: wenn gefunden:
        //  a) von heute, dann aktualisieren
        //  b) nicht von heute, dann neuen Eintrag
 
        if ( !$result || mysql_num_rows($result) == 0 ) // nicht gefunden
        {
            mysql_query("INSERT INTO ".TBL_COUNTER_RECENT." (ip,hit) VALUES ('$ip','$now_mysql')",$sqlConnection);
            mysql_query("INSERT INTO ".TBL_COUNTER." (ip,hit) VALUES ('$ip','$now_mysql')",$sqlConnection);
        }
        else // gefunden
        {
            $hit = mysql_fetch_row($result);
            $hit = intval($hit[0]);
 
            if ( $hit < $_today ) // letzter Besuch war GESTERN
            {
                mysql_query("INSERT INTO ".TBL_COUNTER_RECENT." (ip,hit) VALUES ('$ip','$now_mysql')",$sqlConnection);
                mysql_query("INSERT INTO ".TBL_COUNTER." (ip,hit) VALUES ('$ip','$now_mysql')",$sqlConnection);
            }
            else // letzter Besuch dieser IP war HEUTE
            {
                if ( $_now - $hit > $cfg['reload_time'] ) // neuer Besucher
                {
                    mysql_query("INSERT INTO ".TBL_COUNTER_RECENT." (ip,hit) VALUES ('$ip','$now_mysql')",$sqlConnection);
                    mysql_query("INSERT INTO ".TBL_COUNTER." (ip,hit) VALUES ('$ip','$now_mysql')",$sqlConnection);
                }
                else
                {
                    // NUR DEN AKTUELLSTEN EINTRAG AKTUALISIEREN (!!!)
                    $result = mysql_query("SELECT hit FROM ".TBL_COUNTER_RECENT." WHERE ip = '$ip' AND DAYOFYEAR(hit) = DAYOFYEAR(NOW()) ORDER BY hit DESC",$sqlConnection);
                    $hit    = mysql_fetch_row($result);
                    $hit    = $hit[0];
 
                    mysql_query("UPDATE ".TBL_COUNTER_RECENT." SET hit = '$now_mysql' WHERE ip = '$ip' AND hit = '$hit' LIMIT 1",$sqlConnection);
                    mysql_query("UPDATE ".TBL_COUNTER." SET hit = '$now_mysql' WHERE ip = '$ip' AND hit = '$hit' LIMIT 1",$sqlConnection);
                }
            }
        }
    }
 
    /**
     * Diese Methode löscht, falls die Mini-Tabelle
     * mehr als 10.000 Einträge enthält, alle Aufrufe,
     * die älter als 5 Tage sind. Es ist also
     * sichergestellt, dass in der kleinen Tabelle
     * immer die Daten der letzten 5 Tage enthalten
     * sind.
     * 
     * @param resource $sqlConnection  die zu verwendende Datenbank-Verbindung
     */
    public static function truncateRecent($sqlConnection)
    {
        if(DEBUG) Debug::checkArguments(__METHOD__,"r",$sqlConnection);
 
        $result = mysql_query("SELECT COUNT(*) FROM ".TBL_COUNTER_RECENT,$sqlConnection);
        $result = mysql_fetch_row($result);
 
        if ( $result[0] > 10000 )
        {
            $now = strftime("%Y-%m-%d %H:%M:%S",time()-5*ONE_DAY);
            mysql_query("DELETE FROM ".TBL_COUNTER_RECENT." WHERE hit <= '$now'",$sqlConnection);
        }
    }
}
 
?>

Kommentar verfassen

Fehler gefunden? Doofer Code? Ein kleines "Danke!"? Hinterlasse einfach einen Kommentar.

(muss sein)
(muss nicht sein, wird nicht angezeigt)

Dein Kommentar wird erst nach einer manuellen Prüfung angezeigt.