MySQL-Counter mit IP-Sperre

24Bytes
guten tag,
hier mal ein tutorial, wie man ein mysql-counter mit ip-sperre erstellt (egal ob für wBB oder nicht).
php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
<?php
//counter.php
$host="";  //mysql-host
$user="";  //mysql-user
$pass="";  //mysql-pass
$db="";  //mysql-datenbank
$verbindung=@mysql_connect($host$user$pass) or die ("Fehler!"); //mysql-verbindung
@mysql_select_db($db) or die ("Fehler!"); //mysql-datenbank verbindung
$sid=$_SERVER['REMOTE_ADDR'];  //besucher-ip
$sid.=gethostbyaddr($sid);  //besucher-host
$sid.=date("d.m.Y");  //datum des Besuchs
$sid=md5($sid);  //md5 generierter hash aus ip,host,datum
$check=0;  //abfrage, ob md5 hash in datenbank vorhanden ist
$i=@mysql_query("SELECT sid FROM counter WHERE sid='".$sid."'");
while($i=@mysql_fetch_array($i)){
  $check=1;
}
if($check !==1){  //falls nicht, eintragen
  @mysql_query("INSERT INTO counter (sid) VALUES ('".$sid."')");
}
$ergebnis=@mysql_query("SELECT sid FROM counter");
$counter=@mysql_num_rows($ergebnis);  //eingetragene Hash's zählen.
$counter="Sie sind der ".$counter." Besucher!";
@mysql_close($verbindung);
?>

damit werden alle besucher völlig anonym gezählt und 100% keiner doppelt (es sei den, ip/host/datum ändern sich).
nun muss man nur noch $counter oder echo $counter; irgendwo einfügen!
Broken Sword
Aber das Script wird die Datenbank doch ganz schön belasten, ich stell mir das auf einer Seite mit 100 Besuchern (pro Tag Augenzwinkern ) und mehr vor. Da kommen schon MB zusammen.
Nimm doch einfach noch eine Tabelle und speicher dort die Zahl (INT halt) und die andere erweiterst du mit einer Datumsspalte und die wird nach jedem Tag gelöscht.

Außerdem versteh ich nicht warum du bei jeder mysql-Funktion mit @ die Fehler unterdrückst. Außerdem ist keine Fehlersuche möglich, da nie mit mysql_error() gearbeitet wird.
Auch die while-Schleife in Zeile 15 nenn ich Sinnlos, wie viel Einträge erwartest du? Es kann nur ein Eintrag vorhanden sein.
Game(R)ST
GiNeLi diese Version ist sehr sehr unelegant, besonders was die IP-Speere angeht, das geht etwas besser.

1. 2 Tabellen: für die IP-Speere und eine für den Counter.

2. Lösche alle IPs die älter sind als time()

3. IP wird abgefragt ob vorhanden, wenn nicht--->Counter + 1

3.1 IP-Speeren mit einem time() + 3600 * 12

4. Wenn IP Vorhanden Counterabfrage.



Vorteile:
1. Du kannst den Counter sehr schnell um Gestern/Heute/Gesammt erweitern.
2. Kleine Tabellen mit überschaubaren werten.
3. Nur Zahlenwerte.
4. Wenn IP-Vorhanden nur 3 Datenbankabfragen die sehr klein Sinnd, wenn nicht vorhanden sind es 4.


So dann zu deinem Script:
$ergebnis=@mysql_query("SELECT sid FROM counter");
$counter=@mysql_num_rows($ergebnis); //eingetragene Hash's zählen.
$counter="Sie sind der ".$counter." Besucher!";

würde besser aussehen mit
$ergebnis = @mysql_query("SELECT COUNT(sid) FROM counter");
$counter = mysql_fetch_row($ergebnis)
$counter = $counter[0];

Lies mal http://www.php-einfach.de/einf_mysql_anzahl_zeilen.php

Zudem ist es vollkommen "dumm" unötig lange Hashs in der Datenbank zu speichern, da es nur Speicherplatz kostet. Lieber 2 kleine Tabellen wo aus der einen Ständig die IPs gelöscht werden und die andere hat maximal 3 Datensätze!

@ Broken Sword in einem fertigen Script macht es schon sind mit @ Fehlermeldungen zu unterdrücken. Das wirst du später merken, wobei man für die Datenbankabfragen sowie so lieber entweder ein
@mysql_query() or DIE ("Fehler: $query <br/>".mysql_error()); schreiben sollte oder eben gleich eine eigene Datenbankklasse schreiben die das mit den Fehlern übernimmt.

So und da ich nicht untätig bin-->gleich mal ran gesetzt und getestet.
Für die Datenbankstruktur:
code:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
--
-- Tabellenstruktur für Tabelle `counter`
--
CREATE TABLE `counter` (
  `id` int(1) NOT NULL auto_increment,
  `type` varchar(255),
  `time` int(10) NOT NULL,
  `counter` int(11) NOT NULL,
  PRIMARY KEY  (`id`)
);

-- 
-- Daten für Tabelle `counter`
-- 

INSERT INTO `counter` VALUES (1, 'heute', 1148292091, 0);
INSERT INTO `counter` VALUES (2, 'gestern', 0, 0);
INSERT INTO `counter` VALUES (3, 'gesammt', 0, 0);

-- --------------------------------------------------------

-- 
-- Tabellenstruktur für Tabelle `ipsperre`
-- 

CREATE TABLE `ipsperre` (
  `id` int(11) NOT NULL auto_increment,
  `ip` varchar(50)  NOT NULL,
  `date` int(10) NOT NULL,
  PRIMARY KEY  (`id`)
);

Und der PHP-Code
php:
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:

<?php
@mysql_query("DELETE FROM ipsperre WHERE date < '".time()."'");
$ip $_SERVER['REMOTE_ADDR'];

$abfrage"SELECT COUNT(id) FROM ipsperre WHERE ip = '$ip'";
$count = @mysql_query($abfrage);
$count mysql_fetch_row($count);
$count $count[0];

if($count == 0) {
    $abfrage "SELECT time, counter, id FROM counter";
    $ergebnis = @mysql_query($abfrage);
    while($row =mysql_fetch_assoc($ergebnis)) {
        if($row['id'] == "1") {
            $timestamp time();
            if(date("Ymd",$row['time']) < date("Ymd",$timestamp)) {
                @mysql_query("UPDATE counter SET counter = '".$row['counter']."', time = '".$row['time']."' WHERE ID = '2'");
                @mysql_query("UPDATE counter SET counter = '1', time = '$timestamp' WHERE ID = '1'");
                $ycounter $row['counter'];
                $ncounter 1;
                }//Wenn Gestern, counterstand von Heute nach Gestern verschieben
            else {
                $ncounter $row['counter'] + 1;
                @mysql_query("UPDATE counter SET counter = '$ncounter' WHERE ID =  '1'");
                }//Wenn nicht Gestern um eines erhöhen
            }//Counter Heute
        if($row['id'] == "3") {
            $gcounter $row['counter'] + 1;
            @mysql_query("UPDATE counter SET counter = '$gcounter' WHERE ID = '3'");
            }//Gesammt Counter
        if($row['id'] == "2") {
            $ytime $timestamp 3600*24;
            if(date("Ymd"$row['time']) == date("Ymd"$row['time'])) $ycounter $row['counter']; //Wenn heute - 1 Tag = Gestern nimm den!
        }//Counter Gestern
    }//Counter
    $time time() + 12*3600;
    @mysql_query("INSERT INTO ipsperre (ip, date) VALUES ('$ip','$time')");
}//Wenn IP nicht vorhanden alles weiter Zählen und IP speichern

else {
    $abfrage "SELECT time, counter, id FROM counter";
    $ergebnis = @mysql_query($abfrage);
    while($row=mysql_fetch_assoc($ergebnis)) {
        if($row['id'] == "1") {
            $timestamp time();
            if(date("Ymd",$row['time']) < date("Ymd",$timestamp)) {
                @mysql_query("UPDATE counter SET counter = '".$row['counter']."', time = '".$row['time']."' WHERE ID = '2'");
                @mysql_query("UPDATE counter SET counter = '0', time = '$timestamp' WHERE ID = '1'");
                $ycounter $row['counter'];
                $ncounter 0;
                }//Wenn Gestern, counterstand von Heute nach Gestern verschieben
            else {
                $ncounter $row['counter'];
                }//Wenn nicht Gestern um eines erhöhen
            }//Counter Heute
        if($row['id'] == "3") {
            $gcounter $row['counter'];
            }//Gesammt Counter
        if($row['id'] == "2") {
            $ytime $timestamp 3600*24;
            if(date("Ymd"$row['time']) == date("Ymd"$row['time'])) $ycounter $row['counter']; //Wenn heute - 1 Tag = Gestern nimm den!
        }//Counter Gestern
    }//Counter


}
echo <<<COUNTER
Gesammt: $gcounter <br/>
Gestern: $ycounter <br/>
Heute:   $ncounter <br/>
COUNTER;
?> 

Hab darauf geachtet nicht mehr abfragen wie nötig zu machen. Augenzwinkern Vorallem ist die Datenbank nicht besonders groß was die ip-speere angeht.
Für die IP-Speere
$time = time() + 12*3600;
@mysql_query("INSERT INTO ipsperre (ip, date) VALUES ('$ip','$time')");
Wenn ihr hier eine andere Zeit haben wollt einfach das 12*3600 ab ändern. (Achtung Zeit in Sekunden.
Broken Sword
Zitat:
Original von Game(R)ST
@ Broken Sword in einem fertigen Script macht es schon sind mit @ Fehlermeldungen zu unterdrücken. Das wirst du später merken, wobei man für die Datenbankabfragen sowie so lieber entweder ein
@mysql_query() or DIE ("Fehler: $query <br/>".mysql_error()); schreiben sollte oder eben gleich eine eigene Datenbankklasse schreiben die das mit den Fehlern übernimmt.

Und der wäre? Dass man als User einfach nur sagen kann "Weiß auch nicht warum, aber geht nicht!"?
Sehr unlogisch.


Habe mal mein Script angehangen, in dem auch das Problem mit der Einbindung in der Homepage erledigt sein müsste.
Game(R)ST
Zitat:
Original von Broken Sword
Zitat:
Original von Game(R)ST
@ Broken Sword in einem fertigen Script macht es schon sind mit @ Fehlermeldungen zu unterdrücken. Das wirst du später merken, wobei man für die Datenbankabfragen sowie so lieber entweder ein
@mysql_query() or DIE ("Fehler: $query <br/>".mysql_error()); schreiben sollte oder eben gleich eine eigene Datenbankklasse schreiben die das mit den Fehlern übernimmt.

Und der wäre? Dass man als User einfach nur sagen kann "Weiß auch nicht warum, aber geht nicht!"?
Sehr unlogisch.


Habe mal mein Script angehangen, in dem auch das Problem mit der Einbindung in der Homepage erledigt sein müsste.

Es geht einfach darum das, wenn wir Fehler zeigen, diese entweder direkt zeigen über mysql_error() oder über eine eigene Fehlerbehandlung!
Wenn du eine SQL-Klasse schreibst (hab jetzt eine für mysql und mysqli sowie mssql) legst du die Fehlerbehandlung in die Klasse und schreibst im normal fall ein
function sql_query($querstring) {
$this->querystring = $querystring
$query = @mysql_query($this->querystring) or $this->sql_error(2);
return $query;
}
Um eben so ganz bestimmte Sachen zuverhindern. Nicht jeder muss einen PHP-Fehler sehen und besonders nicht die vom mysql_query Befehel. Offenbart oft schöne Angriffspunkte und Schwächen. Augenzwinkern
Broken Sword
Zitat:
Original von Game(R)ST
Offenbart oft schöne Angriffspunkte und Schwächen. Augenzwinkern

Eigentlich nicht oô
Mir fällt jedenfalls auf Anhieb nichts ein, was dadurch gefährdet sein könnte.
Game(R)ST
Zitat:
Original von Broken Sword
Zitat:
Original von Game(R)ST
Offenbart oft schöne Angriffspunkte und Schwächen. Augenzwinkern

Eigentlich nicht oô
Mir fällt jedenfalls auf Anhieb nichts ein, was dadurch gefährdet sein könnte.

glaub mir, da gibts nen paar nette löcher... besonders wenn register_globals auf on sind. Augenzwinkern
Broken Sword
Zitat:
Original von Game(R)ST
glaub mir

Würde ich das tun, hät ich ja geschrieben, "ok".
Hab ich aber nicht Augenzwinkern