WinFuture-Forum.de: [php/mysql] Counter Mit Ip-sperre - WinFuture-Forum.de

Zum Inhalt wechseln

Nachrichten zum Thema: Entwicklung
Seite 1 von 1

[php/mysql] Counter Mit Ip-sperre


#1 Mitglied ist offline   Slayer 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.476
  • Beigetreten: 12. Dezember 03
  • Reputation: 0
  • Geschlecht:Männlich
  • Wohnort:Baden-Württemberg
  • Interessen:&gt; Internet<br />&gt; Musik<br />&gt; Filme<br />&gt; Events

geschrieben 07. Juni 2005 - 16:04

Hallo zusammen.

Ich habe da mal einen kleinen Overall-Counter für eine Seite programmiert und dann dachte ich, dass ich ihn doch hier mal veröffentlichen kann, vielleicht braucht ja jemand mal einen auf die Schnelle :)

Er funktioniert wunderbar, man kann den Zeit-Intervall für die IP-Sperre variabel einstellen. Als Standard sind 3600 Sekunden (1 Stunde) eingestellt.

Der Counter braucht 2 Tabellen in einer Datenbank.
In der einen werden die IPs gespeichert (maximal 100 dann wird der älteste Eintrag überschrieben) und in der anderen steht der Counterstand.

Man kann die Datei counter.php einfach an jeden Seitenanfang in eine PHP-Datei und beim Aufruf dieser Seite funktioniert der Counter von ganz alleine ;)
Den Counterstand muss man dann selber noch mit einem echo; ausgeben, aber das dürfte jeder selber hinbekommen ;)

Hier mal der Code des Counters:

<?php
function db_connect()
{
	$mysqlhost = "localhost"; # MySQL - Host
	$mysqluser = "xxx"; # MySQL - Benutzername
	$mysqlpass = "xxx"; # MySQL - Passwort
	$mysqlname = "xxx"; # MySQL- Datenbank

	@mysql_connect($mysqlhost, $mysqluser, $mysqlpass)
	or die ("Es konnte keine Verbindung zum Server hergestellt werden!<br>
 	 Bitte die Daten aus der Konfiguration überprüfen!");

	@mysql_select_db($mysqlname)
	or die ("Die Datenbank <b>$dbname</b> existiert nicht!<br>
 	 Bitte die Daten aus der Konfiguration überprüfen!");
}

function get_ip()
{
	$ip = "";
  if (getenv("HTTP_CLIENT_IP")) $ip = getenv("HTTP_CLIENT_IP");
  elseif(getenv("HTTP_X_FORWARDED_FOR")) $ip = getenv("HTTP_X_FORWARDED_FOR");
  elseif(getenv("REMOTE_ADDR")) $ip = getenv("REMOTE_ADDR");
  else $ip = "UNBEKANNT";
	return $ip;
}

db_connect();

#******************************
#* ANFANG | MySQL - Counter
#******************************

$ip_anzahl = 100; // Die maximale Anzahl an IP-Einträgen in der Datenbank
$zeit_intervall = 3600; // Die Zeit (in Sekunden) für den Zeit-Intervall

$nowtime = time();
$nowip = get_ip();

$ip_menge = mysql_num_rows(mysql_query("SELECT zeitstempel FROM counter_ips"));
$ip_select = mysql_query("SELECT zeitstempel FROM counter_ips WHERE ip = '$nowip' ORDER BY zeitstempel DESC LIMIT 1");
$ip_auswahl = mysql_fetch_array($ip_select);

$stop = "";

  if($ip_menge >= $ip_anzahl and mysql_num_rows($ip_select) == 0)
  {
         $del = mysql_query("DELETE FROM counter_ips ORDER BY zeitstempel LIMIT 1");

 	 if($del == true)
 	 { $stop = 0; }

 	 if($nowtime - $ip_auswahl['zeitstempel'] < $zeit_intervall)
 	 { $stop = 1; }
  }

  else
  {
 	 if($nowtime - $ip_auswahl['zeitstempel'] < $zeit_intervall)
 	 { $stop = 1; }
     }

  if($stop != 1 or $stop == 0)
  {
 	 $counter_select = mysql_query("SELECT * FROM counter");
 	 $counterstand = mysql_result($counter_select,0,1);
 	 $counterstand ++;
 	 mysql_query("UPDATE counter SET counterstand = '$counterstand'");

 	 if(mysql_num_rows($ip_select) == 1)
 	 {
    mysql_query("UPDATE counter_ips SET zeitstempel = '$nowtime' ORDER BY zeitstempel DESC LIMIT 1");
 	 }

 	 else
 	 {
    mysql_query("INSERT INTO counter_ips
    (ip, zeitstempel) VALUES ('$nowip', '$nowtime')");
 	 }
  }

#******************************
#* ENDE | MySQL - Counter
#******************************
?>


Der SQL-Code für die Datenbank:

CREATE TABLE counter_ips (
  ip varchar(25) NOT NULL default '',
  zeitstempel int(25) NOT NULL default '0'
);

CREATE TABLE counter (
  id int(10) unsigned NOT NULL auto_increment,
  counterstand int(10) NOT NULL default '0',
  PRIMARY KEY  (id)
);

INSERT INTO counter VALUES (1, 0);


Bitte nicht vergessen die Daten für die MySQL-Connection zu ändern.
Beide Dateien noch im Anhang!

Viel Spaß damit ;)

Angehängte Datei(en)


Der Mensch hat drei Wege, klug zu handeln.
Erstens durch Nachdenken: Das ist der Edelste.
Zweitens durch Nachahmen: Das ist der Leichteste.
Drittens durch Erfahrung: Das ist der Bitterste.

(Konfuzius)
0

Anzeige



#2 Mitglied ist offline   Yalamand 

  • Gruppe: aktive Mitglieder
  • Beiträge: 101
  • Beigetreten: 19. Mai 05
  • Reputation: 0

geschrieben 08. Juni 2005 - 17:30

Kleiner Verbesserungsvorschlag: Es werden keine 25 Bytes für eine IP gebraucht. Es reichen 4 bytes (also int(11) bei mysql), wenn du die folgenden Funktionen verwendest:

int = ip2long(IP_ADDRESSE) //zum speichern
IP_ADDRESSE = long2ip(int) // zum auslesen

Hat den Vorteil das bei vielen Besuchern viel weniger Speicher benötigt wird und die Indizierung für Suchen und WHERE-Anfragen bedeutend schneller gehen, die sich auf die IP-Spalte beziehen.

Auch auf die create tables aufpassen... int(25) wäre nach Definition von mysql eine int mit einer länge von 25 Zeichen. Eine INT kann braucht aber nur 11 Zeichen, auch nicht 10 oder weniger :ph34r:

Dieser Beitrag wurde von Yalamand bearbeitet: 08. Juni 2005 - 17:46

0

#3 Mitglied ist offline   Slayer 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.476
  • Beigetreten: 12. Dezember 03
  • Reputation: 0
  • Geschlecht:Männlich
  • Wohnort:Baden-Württemberg
  • Interessen:&gt; Internet<br />&gt; Musik<br />&gt; Filme<br />&gt; Events

geschrieben 08. Juni 2005 - 20:04

Ah, dankeschön, man lernt nie aus.
Also kann ich für INT immer 11 nehmen?

Ich ermittle die IP-Adresse mit folgender Funktion:

function get_ip()
{
	$ip = "";
  if (getenv("HTTP_CLIENT_IP")) $ip = getenv("HTTP_CLIENT_IP");
  elseif(getenv("HTTP_X_FORWARDED_FOR")) $ip = getenv("HTTP_X_FORWARDED_FOR");
  elseif(getenv("REMOTE_ADDR")) $ip = getenv("REMOTE_ADDR");
  else $ip = "UNBEKANNT";
	return $ip;
}

Der Mensch hat drei Wege, klug zu handeln.
Erstens durch Nachdenken: Das ist der Edelste.
Zweitens durch Nachahmen: Das ist der Leichteste.
Drittens durch Erfahrung: Das ist der Bitterste.

(Konfuzius)
0

#4 Mitglied ist offline   Yalamand 

  • Gruppe: aktive Mitglieder
  • Beiträge: 101
  • Beigetreten: 19. Mai 05
  • Reputation: 0

geschrieben 08. Juni 2005 - 20:18

Zitat (Slayer: 08.06.2005, 21:04)

Ah, dankeschön, man lernt nie aus.
Also kann ich für INT immer 11 nehmen?

Ich ermittle die IP-Adresse mit folgender Funktion:

<{POST_SNAPBACK}>


Ja, INT sollte immer 11 sein. Ansonsten sollte ein anderer Datentyp verwendet werden, z.B. SMALLINT. Eine INT(4) würde zwar 4 Bytes belegen, aber nur die ersten 4 Zeichen würden gespeichert werden (oder die letzten? unsicher). z.B. bei der Zahl 123456789 würde nur 1234 oder 6789 gespeichert werden. Die Zahl in der Klammer ist bei MySQL 4.x immer die Zeichenlänge, egal welcher Datentyp.

Siehe auch http://dev.mysql.com...eric-types.html da steht genau beschrieben welcher Datentyp wieviel Bytes belegt und wie die range ist.

Die Funktion sähe dann ungefähr so aus:

function get_ip()
{
  if(isset($_SERVER['HTTP_CLIENT_IP'])) {
 	 return ip2long($_SERVER['HTTP_CLIENT_IP']);
  } elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
 	 return ip2long($_SERVER['HTTP_X_FORWARDED_FOR']);
  } elseif(isset($_SERVER['REMOTE_ADDR'])) {
 	 return ip2long($_SERVER['REMOTE_ADDR']);
  } else {
 	 return NULL;
  }
}


Ich verwende hier $_SERVER statt getenv() da es die eigentlich bessere Syntax ist, die auch weniger Probleme bei Cross-Systemen macht, also Linux <> Windows kompatibilität.

NULL gebe ich zurück, da es besser für Vergleiche ist bei PHP. z.B. is_null($ip) könnte Prüfen ob ein Fehler vorliegt. Weil 0 eine gültige IP ist, ist es hier der bessere weg.

Ich mache überall returns, da ein extra abspeichern in neuen Variablen eigentlich unnötig ist und so ein schneller Rücksprung geschehen kann.

WICHTIG: Die IP Spalte in der Datenbank sollte SIGNED sein, da ip2long auch den negativen Zahlenbereich benutzt.

Was genau willst du mit der counter Tabelle? Ich komme nicht direkt auf den Sinn. Wenn du jeden einzelnen Datensatz +1 machen willst reicht eigentlich ein

UPDATE counter SET counterstand = counterstand + 1


im MySQL da dies unterstützt und den Aufwand im PHP vermindert.

Dieser Beitrag wurde von Yalamand bearbeitet: 08. Juni 2005 - 20:27

0

#5 Mitglied ist offline   Slayer 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.476
  • Beigetreten: 12. Dezember 03
  • Reputation: 0
  • Geschlecht:Männlich
  • Wohnort:Baden-Württemberg
  • Interessen:&gt; Internet<br />&gt; Musik<br />&gt; Filme<br />&gt; Events

geschrieben 08. Juni 2005 - 20:26

Danke @Yalamand

Ich dachte immer, dass die Zahl für die maximale Länge ist. Was würdest du dann bei ID empfehlen, auch 11? bei TYNIINT verwende ich immer 1.
Bei IP-Adressen z.B. VARCHAR(25), was würdest du mir da empfehlen?

Danke wegen der get_ip()-Funktion!

Dieser Beitrag wurde von Slayer bearbeitet: 08. Juni 2005 - 20:27

Der Mensch hat drei Wege, klug zu handeln.
Erstens durch Nachdenken: Das ist der Edelste.
Zweitens durch Nachahmen: Das ist der Leichteste.
Drittens durch Erfahrung: Das ist der Bitterste.

(Konfuzius)
0

#6 Mitglied ist offline   Yalamand 

  • Gruppe: aktive Mitglieder
  • Beiträge: 101
  • Beigetreten: 19. Mai 05
  • Reputation: 0

geschrieben 08. Juni 2005 - 20:45

Zitat (Slayer: 08.06.2005, 21:26)

Danke @Yalamand

Ich dachte immer, dass die Zahl für die maximale Länge ist. Was würdest du dann bei ID empfehlen, auch 11? bei TYNIINT verwende ich immer 1.
Bei IP-Adressen z.B. VARCHAR(25), was würdest du mir da empfehlen?

Danke wegen der get_ip()-Funktion!
<{POST_SNAPBACK}>


Gab kein Problem mit deiner, war nur ein Vorschlag wie man es machen könnte wenn man die IP als INT speichern will <_<

Gerade noch einmal nachgeschaut in der Doku, INT(4) bewirkt z.B. bedeutet das du 12345 zwar speichern kannst, aber die (4) bewirkt das die Anzeige(soweit ich das jetzt nachgelesen habe) es 2345 ist. Gespeichert wird aber 12345. TINYINT(1) ist ein bool, aber wie es zeigt, wird trotzdem ein BYTE gespeichert, auch wenn ein bool normalerweise nur ein BIT ist. Dort ist es egal ob du bei einer PHP-Anwendung (1) oder (4) nimmst. -128 würde bloss zu 8.

Wie gesagt, les dich mal durch den Link im vorherigen Post :P Es ist für die maximale Länge. 1234 hätte eine Länge von 4. Wenn du INT(10) machst, riskierst du die erste Zahl zu verlieren. Rein theoretisch.

IP-Adressen sollten INT(11) sein, ganz normal... ist eine saubere Definition. Ein VARCHAR(25) gibt natürlich an das Zeichen bis zu einer Länge von 25 gespeichert werden. Bei DECIMAL z.B. ist es die Precision, z.b. DECIMAL(8) oder DECIMAL(8,2).
0

#7 Mitglied ist offline   Slayer 

  • Gruppe: aktive Mitglieder
  • Beiträge: 1.476
  • Beigetreten: 12. Dezember 03
  • Reputation: 0
  • Geschlecht:Männlich
  • Wohnort:Baden-Württemberg
  • Interessen:&gt; Internet<br />&gt; Musik<br />&gt; Filme<br />&gt; Events

geschrieben 08. Juni 2005 - 20:59

Danke nochmals @Yalamand
Dann sollte ich bei einem Zeitstempel auch 11 verwenden, werde meine Datenbanken mal so anpassen. Hat zwar jetzt nichts mit dem Counter zu tun, hast mir aber trotzdem weitergeholfen <_<
Der Mensch hat drei Wege, klug zu handeln.
Erstens durch Nachdenken: Das ist der Edelste.
Zweitens durch Nachahmen: Das ist der Leichteste.
Drittens durch Erfahrung: Das ist der Bitterste.

(Konfuzius)
0

Thema verteilen:


Seite 1 von 1

1 Besucher lesen dieses Thema
Mitglieder: 0, Gäste: 1, unsichtbare Mitglieder: 0