Diskussion Klickzaehler
Rolf
- perl
Hallo, es muss am Wetter liegen: Regentropfen on my Window klopfen PERL'len builden sich ;-) .. ist das folgende Script ok? Wenn ja, wer's braucht nehme es und lasse es auf seiner Site brummen ODER schreibe hier seine Kritik! ; Viele Grüße, Rolf
***
$link = "http://www.i-netlab.de";
$local_dir = "/home/i-netlab.de";
$count_file = "count.dat";
$lock_file = "count.lock";
&count; # erst Zählen...
&redir; # dann Umleiten & Tschuess
sub count{
my $cx;
my $timeout = 10; # Sekunden warten auf Freigabe einer vergessenen Sperre
my $lockfile = "$local_dir/$lock_file";
my $countfile = "$local_dir/$count_file";
while(-e $lockfile && ( stat($lockfile))[9] + $timeout > time ){
sleep(1);
}
open LOCK, ">$lockfile" die "$!";
open (CF, "+<$countfile") die "$!";
seek (CF, 0, 0);
$cx = <CF>;
$cx++;
seek (CF, 0, 0);
print CF "$cx\n";
close CF;
close LOCK;
unlink($lockfile);
}
sub redir{
use CGI;
my $q = new CGI;
print $q->redirect($link);
}
Hi,
hehehe...das Angebot ein CGI-Skript anzuschauen lass ich mir nicht 2 mal geben :))
Zuallererst: Ne schoene Header-Kommentar mit deinen Namen etc.
waere schoen. Noch besser waere es, wenn du auch eine versionsnummer mitfuehrst.
RCS macht sich gut...
Klicks auf einen Link zählen und umleiten auf Link-URL
Script Name: "klick_redir.pl"
Anstelle der Referenz auf den Link folgendes in der HTML-Datei notieren
a href="/cgi-bin/klick_redir.pl"
Beginn Konfiguration
»» # wohin umleiten, kompletter http-Pfad
»» $link = "http://www.i-netlab.de";
»» # Absoluter lokaler Pfad zum Verzeichnis des Klickzählers, kein Slash am Ende
»» $local_dir = "/home/i-netlab.de";
»»
»» # Name der Zählerdatei die Datei von Hand anlegen
»» $count_file = "count.dat";
»»
»» # Name der Sperrdatei, verhindert Mehrfachzugriff auf "Zählerdatei"
»» $lock_file = "count.lock";
Ende Konfiguration
Aufruf der Funktionen
&count; # erst Zählen...
&redir; # dann Umleiten & Tschuess
Wenn du hier ein exit(); einbaust ists nicht falsch und nicht anders, aber es sieht besser aus und hilft beim Debugging.
Sub-Funktionen...
Die Zählfunktion
sub count{
»» my $cx;
»» my $timeout = 10; # Sekunden warten auf Freigabe einer vergessenen Sperre
»» my $lockfile = "$local_dir/$lock_file";
»» my $countfile = "$local_dir/$count_file";
»» # Prüfen ob eine Sperre vorliegt, ggf. Sperre setzen
»» while(-e $lockfile && ( stat($lockfile))[9] + $timeout > time ){
»» sleep(1);
»» }
»» open LOCK, ">$lockfile" die "$!";
Da wuerde ich lieber symlink() nehmen.
Oder, da das ja unter PeeCee nicht geht, es so machen:
unless ($OS) {
unless ($OS = $^O) {
require Config;
$OS = $Config::Config{'osname'};
}
}
if ($OS =~ /Win/i) {
open LOCK, ">$lockfile" die "$!";
} else {
symlink($countfile, $lockfile);
}
Warum? Die Linkfunktionen sind atomar, open() und close() nicht.
Und das sogar ueber Mouting-Points hinweg. (flock() versagt da ja).
»» # CountFile zum Lesen und Schreiben öffnen
Noch sicherer waere, wenn du jetzt zusaetzlich doch noch flock()
nutzen wuerdest :)
»» open (CF, "+<$countfile") die "$!";
»» seek (CF, 0, 0);
»» $cx = <CF>;
»» $cx++;
»» seek (CF, 0, 0);
»» print CF "$cx\n";
»» close CF;
»» # Sperre wieder aufheben
»» close LOCK;
»» unlink($lockfile);
}
Die Umleitfunktion
sub redir{
»» use CGI;
»» my $q = new CGI;
»» print $q->redirect($link);
}
Urg! Fuer 4 Zeilen, die du ohne CGI-Modul schreiben kannst, bindest du
das ganze Ding ein?!? Auch wenn das Ding mit Autoloadern arbeitet, verschwendest
du dort ganz schoen Speicher.
Machs lieber so:
sub redir {
print "Status: 302 Found\n";
print "Location: $link\n";
print "URI: <$link>\n";
print "Content-type: text/html\r\n\r\n";
}
Zuallerletzt:
Was passiert, wenn nun im Programm ein Fehler auftritt, und ein die() ausgefuehrt wird?
Du bekommst ein Error 500, weil ja kein richtiger Header zurueckgegeben wird.
Hier solltest du also ggf. statt die() einfach redir() aufrufen oder eine
eigene Fehlerroutine schreiben.
Ciao,
Wolfgang
Vielen Dank und herzliche Grüße; Rolf