Zeilenumbruch in Perl-GBook Skript
schmaidt
- perl
0 Thomas Mell0 Matti Maekitalo0 Buggi0 Buggi0 FrankS0 schmaidt0 Matti Maekitalo0 FrankS
0 schmaidt
Erstmal ein großes Danke das Ihr es mit dem neuen Forum geschafft habt!!!
Und vielleicht kann mir dadurch auch endlich jemand bei meinem Problem helfen, was in anderen Foren nicht geschafft wurde.
Es geht um folgendes: Ich habe mir schon vor einiger Zeit ein eigenes Gästebuch Skript in Perl geschrieben, welches Recht simpel ist aber sehr gut seine Arbeit tut. Allerdings habe ich es immer noch nicht hingekriegt, dass wenn man im Eingabefeld der Nachricht durch ENTER einen Zeilenumbruch erzwingen will, dass dieser dann auch wirklich in der Nachricht gezeigt wird!
Falls mir jemand helfen kann und dazu aber vielleicht das Skript sehen muss, dem kann ich das natürlich zuschicken oder teilweise hier posten!
Danke schonmal, schmaidt
Hallo,
wenn ich dich richtig verstehe meinst du die Nachricht nach dem Verschicken an den Server !? Oder etwa beim schreiben im Textfeld ?
Bei ersteren mußt du die Zeilenumbrüche durch <br>`s ersetzen.
$text =~ s/\n/<br>/g
viele Grüße
Thomas
Hallo
Allerdings habe ich es immer noch nicht hingekriegt, dass wenn man im Eingabefeld der Nachricht durch ENTER einen Zeilenumbruch erzwingen will, dass dieser dann auch wirklich in der Nachricht gezeigt wird!
So ein kleiner Teil des Scriptes wäre schon ganz gut, aber probiers mal so:
use strict;
use CGI;
my $q = new CGI;
$_ = $q->param('feld');
s/\n/<br>/g;
Und das funktioniert nicht?
Tschö Matti
Moinmoin!
[...] Allerdings habe ich es immer noch nicht hingekriegt, dass wenn man im Eingabefeld der Nachricht durch ENTER einen Zeilenumbruch erzwingen will, dass dieser dann auch wirklich in der Nachricht gezeigt wird!
Wenn im Eingabefeld ein Zeilenumbruch vorkommt, wird dieser auch als Zeilenumbruch übergeben und hinterher in die Nachricht ge-print-et. Guck dir mal den Sourcecode der ausgegebenen HTML-Seite an, da sind die Zeilenumbrüche drin ;)
Das simple Problem liegt darin, dass ein Zeilenumbruch im HTML-Source nicht als solcher im Browser angezeigt wird. Ersetze einfach alle in der Nachricht vorkommenden Zeilenumbrüche durch <br>-Tags, dann werden sie auch im Browser angezeigt:
$nachrichtentext =~ s/\n/<br>/;
beim Speichern des Gästebucheintrags dürfte ausreichen.
Liebe Grüße
Buggi
[Nachtrag]
$nachrichtentext =~ s/\n/<br>/;
muss
$nachrichtentext =~ s/\n/<br>/g;
heißen, da sonst nur der erste vorkommende Zeilenumbruch ersetzt wird (ups).
Liebe Grüße
Buggi
PS: Lustig, was hier jetzt schon für ein reger Verkehr ist *g*
Moin Buggi!
$nachrichtentext =~ s/\n/<br>/g;
Windows- und UNIX-Browser senden als Zeilenumbruch unterschiedliche Zeichen.
Windows: 0Dh 0Ah (\r\n)
UNIX: 0Ah (\n)
Damit nicht ein einsames 0Dh im Text stehen bleibt, sollte so:
$nachrichtentext =~ s/(\r\n)|(\n)/<BR>/g;
ersetzt werden.
Gruß Frank
Danke ja, aber ich weiss leider immer noch nicht, wohin diese zeilen im Quellcode hinkommen. In meinem zweiten Posting habe ich den Quelltext auch gepostet, kann mir nicht jemand sagen, wohin die Befehle müssen?
Bitte & Danke, schmaidt
Hallo FrankS
Windows- und UNIX-Browser senden als Zeilenumbruch unterschiedliche Zeichen.
Windows: 0Dh 0Ah (\r\n)
UNIX: 0Ah (\n)
Und sendet der Mac nicht einfach nur \r als Zeilenumbruch?
Welche Lösung gibt es dann?
s/\r\n/<br>/g;
s/\r/<br>/g;
s/\n/<br>/g;
Jedenfalls das erste muss da stehen bleiben.
Tschö Matti
Hi Matti
Und sendet der Mac nicht einfach nur \r als Zeilenumbruch?
Interessant, das muß ich mal probieren, dann hätte eins meiner Scripte ja noch einen dicken Fehler, der u.U. zur Zerstörung von Daten führen könnte *schwitz*
Wie wär's dann mit
$nachrichtentext =~ s/(\r)|(\r\n)|(\n)/<BR>/g;
Gruß Frank
Hmmm, die Sache ist, dass ich mich so gut nun auch nicht auskenne mit Perl und den Speichern-Teil aus einem anderen übernommen hab. Die Befehle die Ihr mir gepostet habt, kenne ich, aber mein Problem liegt glaube ich da, dass ich nicht genau weiss, wo sie hingehören. I
Ich poste Euch mal den Teil, in dem ich glaube, dass die Sachen hinmüssen.
use strict; # enforce declarations and quoting
use CGI qw(:standard); # import shortcuts
sub bail { # Funktion zur Ausgabe bei Fehlern
my $error = "@_";
print h1("Unerwarteter Fehler"), p($error), end_html;
die $error;
}
my(
$CHATNAME, # Name der Datei der Gästebucheinträge
$MAXSAVE, # Wieviele Einträge sind möglich
$TITLE, # Seitentitel- und Überschrift
$cur, # Neuer Eintrag ins Gästebuch
@entries, # Alle Einträge
$entry, # Ein einzelner Eintrag
$LOCK_EX, # hardcoded value for flock
$counter, # Nummerierung der Einträge
$help,
);
$LOCK_EX = 2; # hardcoded value for flock
$TITLE = "schmaidt.de - guestbook";
$CHATNAME = "../CHATFILE"; # Pfad der Datei der Einträge
$MAXSAVE = 900;
$cur = CGI->new(); # current request
if ($cur->param("message")) { # Es existiert ein Eintrag
$cur->param("date", scalar localtime); # aktuelle Zeit
@entries = ($cur); # Speichern des Eintrags in das Array
}
open(CHANDLE, "+< $CHATNAME") ||
bail("cannot open $CHATNAME: $!");
flock(CHANDLE, $LOCK_EX) || bail("cannot flock $CHATNAME: $!");
while (!eof(CHANDLE) && @entries < $MAXSAVE) {
# pass the filehandle by reference
$entry = CGI->new(\*CHANDLE);
push @entries, $entry;
}
seek(CHANDLE, 0, 0) || bail("cannot rewind $CHATNAME: $!");
foreach $entry (@entries) {
$entry->save(\*CHANDLE); # pass the filehandle by reference
}
truncate(CHANDLE, tell(CHANDLE)) ||
bail("cannot truncate $CHATNAME: $!");
close(CHANDLE) || bail("cannot close $CHATNAME: $!");
Ich hab jetzt erstmal einen ziemlich großen Teil gepostet, weil ich sicher gehen wollte, dass der richtige Bereich doch noch fehlt. Wäre Euch also echt dankbar, wenn Ihr mir sagen könntet wo es hin soll!
Danke, schmaidt
Hi nochmal!
Die Befehle die Ihr mir gepostet habt, kenne ich, aber mein Problem
liegt glaube ich da, dass ich nicht genau weiss, wo sie hingehören.
if ($cur->param("message")) { # Es existiert ein Eintrag
An dieser Stelle prüfts Du, ob jemand einen neuen Eintrag inzufügen will.
im Parameter "message" steht offensichtlich der Text.
$cur->param("date", scalar localtime); # aktuelle Zeit
Hier wird noch die aktuelle Zeit eingefügt
@entries = ($cur); # Speichern des Eintrags in das Array
zur Weiterverarbeitung abgespeichert. Davor muß nun diese Änderung rein.
}
Also so (zum Verständnis schön in einzelnen Schritten):
if ($cur->param("message")) { # Es ...
###neu
$temp = $cur->param("message"); # lesen
$temp = s/(\r\n)|(\n)/<BR>/g; # \n gegen <BR> tauschen
$cur->param("message", $temp); # schreiben
###
$cur->param("date", scalar localtime); # aktuelle Zeit
@entries = ($cur); # Speichern ...
}
Über einen Teil sollte aber auch noch diskutiert werden:
open the file for read-write (preserving old contents)
open(CHANDLE, "+< $CHATNAME") || bail("cannot open $CHATNAME: $!");
get exclusive lock on the guestbook
($LOCK_EX == exclusive lock)
flock(CHANDLE, $LOCK_EX) || bail("cannot flock $CHATNAME: $!");
Das flock soll verhindern, das die Datei von 2 Prozessen gleichzeitig geöffnet wird (2 User posten gleichzeitig einen Eintrag). Über diesen Mechanismus wurde schon viel diskutiert...
Eigentlich funktioniert das so:
Prozess1: öffnet die Datei
Prozess1: setzt exclusive lock
Prozess1: bearbeitet Datei
Prozess1: Schließt Datei hebt damit den lock wieder auf
Jetzt mit 2 Prozessen:
Prozess1: öffnet die Datei
Prozess1: setzt exclusive lock
Prozess2: öffnet die Datei
Prozess2: will exclusive lock setzen,
kann aber nicht, da bereits
gesetzt, wird vertagt
Prozess1: bearbeitet Datei
Prozess1: Schließt Datei hebt
damit den lock wieder auf
Prozess2: wird geweckt, kann nun
exclusive lock setzen
Prozess2: bearbeitet Datei
Prozess2: Schließt Datei hebt
damit den lock wieder auf
(Vorausstzung: open und flock sind auf Deinem Server richtig implementiert - Stichwort atomare Befehle)
Damit merkt der User, der den 2. Prozess gestartet hat, nicht, dass ein Zugriffskonflikt stattfand, es dauert nur etwas länger. Bei Dir passiert aber etwas anderes: Der 2.Prozess wird mit einer Fehlermeldung beendet. Es reicht also diese Zeile:
flock(CHANDLE, $LOCK_EX);
Na dann,
Gruß Frank
P.S. Hoffentlich ist die Formatierung nach dem Absenden noch lesbar.
Hi nochmal!
Die Befehle die Ihr mir gepostet habt, kenne ich, aber mein Problem
liegt glaube ich da, dass ich nicht genau weiss, wo sie hingehören.
if ($cur->param("message")) { # Es existiert ein Eintrag
An dieser Stelle prüfts Du, ob jemand einen neuen Eintrag inzufügen will.
im Parameter "message" steht offensichtlich der Text.
$cur->param("date", scalar localtime); # aktuelle Zeit
Hier wird noch die aktuelle Zeit eingefügt
@entries = ($cur); # Speichern des Eintrags in das Array
zur Weiterverarbeitung abgespeichert. Davor muß nun diese Änderung rein.
}
Also so (zum Verständnis schön in einzelnen Schritten):
if ($cur->param("message")) { # Es ...
###neu
$temp = $cur->param("message"); # lesen
$temp = s/(\r\n)|(\n)/<BR>/g; # \n gegen <BR> tauschen
$cur->param("message", $temp); # schreiben
###
$cur->param("date", scalar localtime); # aktuelle Zeit
@entries = ($cur); # Speichern ...
}
Über einen Teil sollte aber auch noch diskutiert werden:
open the file for read-write (preserving old contents)
open(CHANDLE, "+< $CHATNAME") || bail("cannot open $CHATNAME: $!");
get exclusive lock on the guestbook
($LOCK_EX == exclusive lock)
flock(CHANDLE, $LOCK_EX) || bail("cannot flock $CHATNAME: $!");
Das flock soll verhindern, das die Datei von 2 Prozessen gleichzeitig geöffnet wird (2 User posten gleichzeitig einen Eintrag). Über diesen Mechanismus wurde schon viel diskutiert...
Eigentlich funktioniert das so:
Prozess1: öffnet die Datei
Prozess1: setzt exclusive lock
Prozess1: bearbeitet Datei
Prozess1: Schließt Datei hebt damit den lock wieder auf
Jetzt mit 2 Prozessen:
Prozess1: öffnet die Datei
Prozess1: setzt exclusive lock
Prozess2: öffnet die Datei
Prozess2: will exclusive lock setzen,
kann aber nicht, da bereits
gesetzt, wird vertagt
Prozess1: bearbeitet Datei
Prozess1: Schließt Datei hebt
damit den lock wieder auf
Prozess2: wird geweckt, kann nun
exclusive lock setzen
Prozess2: bearbeitet Datei
Prozess2: Schließt Datei hebt
damit den lock wieder auf
(Vorausstzung: open und flock sind auf Deinem Server richtig implementiert - Stichwort atomare Befehle)
Damit merkt der User, der den 2. Prozess gestartet hat, nicht, dass ein Zugriffskonflikt stattfand, es dauert nur etwas länger. Bei Dir passiert aber etwas anderes: Der 2.Prozess wird mit einer Fehlermeldung beendet. Es reicht also diese Zeile:
flock(CHANDLE, $LOCK_EX);
Na dann,
Gruß Frank
P.S. Hoffentlich ist die Formatierung nach dem Absenden noch lesbar.
DANKE DANKE DANKE. So hat es dann endlich geklappt. Allerdings hattest Du einen kleinen Tipfehler drin. Es muss nämlich
$temp =~ s/(\r\n)|(\n)/<BR>/g; statt
$temp = s/(\r\n)|(\n)/<BR>/g; heißen!
Aber das hab selbst ich - die Laie - noch alleine hingekriegt!
Danke nochmals, schmaidt
Hallo Schmaidt
DANKE DANKE DANKE. So hat es dann endlich geklappt. Allerdings hattest Du einen kleinen Tipfehler drin. Es muss nämlich
$temp =~ s/(\r\n)|(\n)/<BR>/g; statt
$temp = s/(\r\n)|(\n)/<BR>/g; heißen!
Ich könnte mich ja jetzt rausreden, so nach dem Motto: Extra reingemacht, den Fehler, ein bischen Perl-Übung kann ja nicht schaden ;-)
Aber so ist das, wenn man ungetesteten Code postet.
Bis dann
Gruß Frank
Hi nochmal!
Die Befehle die Ihr mir gepostet habt, kenne ich, aber mein Problem
liegt glaube ich da, dass ich nicht genau weiss, wo sie hingehören.
if ($cur->param("message")) { # Es existiert ein Eintrag
An dieser Stelle prüfts Du, ob jemand einen neuen Eintrag inzufügen will.
im Parameter "message" steht offensichtlich der Text.
$cur->param("date", scalar localtime); # aktuelle Zeit
Hier wird noch die aktuelle Zeit eingefügt
@entries = ($cur); # Speichern des Eintrags in das Array
zur Weiterverarbeitung abgespeichert. Davor muß nun diese Änderung rein.
}
Also so (zum Verständnis schön in einzelnen Schritten):
if ($cur->param("message")) { # Es ...
###neu
$temp = $cur->param("message"); # lesen
$temp = s/(\r\n)|(\n)/<BR>/g; # \n gegen <BR> tauschen
$cur->param("message", $temp); # schreiben
###
$cur->param("date", scalar localtime); # aktuelle Zeit
@entries = ($cur); # Speichern ...
}
Über einen Teil sollte aber auch noch diskutiert werden:
open the file for read-write (preserving old contents)
open(CHANDLE, "+< $CHATNAME") || bail("cannot open $CHATNAME: $!");
get exclusive lock on the guestbook
($LOCK_EX == exclusive lock)
flock(CHANDLE, $LOCK_EX) || bail("cannot flock $CHATNAME: $!");
Das flock soll verhindern, das die Datei von 2 Prozessen gleichzeitig geöffnet wird (2 User posten gleichzeitig einen Eintrag). Über diesen Mechanismus wurde schon viel diskutiert...
Eigentlich funktioniert das so:
Prozess1: öffnet die Datei
Prozess1: setzt exclusive lock
Prozess1: bearbeitet Datei
Prozess1: Schließt Datei hebt damit den lock wieder auf
Jetzt mit 2 Prozessen:
Prozess1: öffnet die Datei
Prozess1: setzt exclusive lock
Prozess2: öffnet die Datei
Prozess2: will exclusive lock setzen,
kann aber nicht, da bereits
gesetzt, wird vertagt
Prozess1: bearbeitet Datei
Prozess1: Schließt Datei hebt
damit den lock wieder auf
Prozess2: wird geweckt, kann nun
exclusive lock setzen
Prozess2: bearbeitet Datei
Prozess2: Schließt Datei hebt
damit den lock wieder auf
(Vorausstzung: open und flock sind auf Deinem Server richtig implementiert - Stichwort atomare Befehle)
Damit merkt der User, der den 2. Prozess gestartet hat, nicht, dass ein Zugriffskonflikt stattfand, es dauert nur etwas länger. Bei Dir passiert aber etwas anderes: Der 2.Prozess wird mit einer Fehlermeldung beendet. Es reicht also diese Zeile:
flock(CHANDLE, $LOCK_EX);
Na dann,
Gruß Frank
P.S. Hoffentlich ist die Formatierung nach dem Absenden noch lesbar.
Achso, und danke natürlich auch für den Tip mit dem flock. Habe ich gleich geändert und schon einmal ausprobiert. Auch das klappt!
Danke, schmaidt