PHP - probleme mit Post bei einer Shoutbox

der-gott

Vice Admiral Special
Mitglied seit
02.05.2006
Beiträge
763
Renomée
1
Standort
Frankfurt a.M (um die Ecke jedenfalls =)
Schönen guten Tag ... habe ein kleines Problemchen :D

und zwar bei bei meienr Shoutbox (hier ansehen gibt es einen kleinen aber feinen und vorallem störenden Fehler.
Wenn man eine Nachricht eingibt und dann auf F5 drückt um die (gesamte) Seite zu aktualisieren wird der EIntrag nochmal gepostet. Warum er das macht (neuer Aufruf der Post Action) ist mir halbwegs klar nur wie um alles in der Welt kann ich das unterbinden *noahnung* ??

hier mal der Code :

<HTML><HEAD><TITLE>.. www.der-gott.de</TITLE>
<meta http-equiv=refresh content=10;url=http://www.der-gott.de/msg.php>
<style type="text/css">
<!--
A:link {text-decoration:none; border-bottom: 1px dotted; color: #000000; }
A:visited {text-decoration:none; border-bottom: 1px dotted; color:#000000; }
A:hover {color:#ffcc00; text-decoration: underline; }
a:visited:hover {text-decoration:none; border-bottom: 1px solid; color: #ffcc00; }-->
input{font: 7px Verdana color: #000000; border: 1px solid #000000}
.button{border:1px solid #000000;color:#000000;background:#DDDDDD;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:9px;}
.textfeld{border:1px solid #000000; color:#000000;background:#DDDDDD;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:9px;}
body {
font-family:verdana;
font-size:7pt;
color="#000000"
}
-->
</style>
<META content="NOTEPAD" name=GENERATOR>
</HEAD>
<BODY bgcolor="#FFFFFF" border="0" bgproperties="fixed"><center><table width=135>
<font face="Geneva,Verdana,Arial,Helvetica,Geneva" style="font-size:6px;">
<?
$person = str_replace ("\n"," ", $person);
$person = str_replace ("<", " ", $person);
$person = str_replace (">", " ", $person);
$person = stripslashes ($person);
?>
<form action="msg.php" method="post">
<table>
<tr>
<td><font face="Verdana" size="1,5"><b>Nick:</b></td>
<td><input type="text" name="person" class=textfeld size="20" maxlength="20" value="<? echo $person; ?>"><br></td>
</tr>
<tr>
<td><font face="Verdana" size="1,5"><b>Message:</b></td>
<td><input type="text" name="message" class=textfeld size="20" maxlength="90"><br></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="hinschreiben" class=button></td>
</tr>

</table>

</form>
<?php
$message = $_POST["message"];
$person = $_POST["person"];
$chat_file_ok = "msg.txt";
$chat_lenght = 15;
$max_single_msg_lenght = 1024;
$max_file_size = $chat_lenght * $max_single_msg_lenght;
$file_size= filesize($chat_file_ok);
if ($file_size > $max_file_size) {
$lines = file($chat_file_ok);
$a = count($lines);
$u = $a - $chat_lenght;
for($i = $a; $i >= $u ;$i--){
$msg_old = $lines[$i] . $msg_old;
}
$deleted = unlink($chat_file_ok);
$fp = fopen($chat_file_ok, "a+");
$fw = fwrite($fp, $msg_old);
fclose($fp);
}
$msg = str_replace ("\n"," ", $message);
$msg = str_replace ("\n"," ", $message);
$msg = str_replace ("<", " ", $msg);
$msg = str_replace (">", " ", $msg);
$msg = stripslashes ($msg);
if ($msg != ""){
$fp = fopen($chat_file_ok, "a+");
$fw = fwrite($fp, "\n<b>$person :</b> $msg");
fclose($fp);
}
$lines = file($chat_file_ok);
$a = count($lines);
$u = $a - $chat_lenght;
for($i = $a; $i >= $u ;$i--){
echo $lines[$i] . "<br>";
}
?>
</table>
</BODY>
</HTML>

Ich hoffe mir kann das jemand erklären.
Danke schonmal und schönen Vormittag noch :D
 
Tach,

wenn du auf den "hinschreiben" Button drückst, wird die gesamte Seite neugeladen. Nur das diesesmal ein paar Daten mitgesendet werden, nämlich die die du eingegeben hast. Drückst du auf "neu laden", wird nur der letzte HTTP Transfer erneut gesendet, also wieder genau die selben Daten wie beim Eintragen. Und damit erscheint der Post nochmal. Der Browser weist einen deswegen extra darauf hin, ob man das ganze wirklich neu laden will, weil man eben diese POST Daten mitsendet.

Was man dagegen machen kann:
  1. Meldungen lesen und beachten. :D *SCNR*
  2. Nach dem Posten auf eine andere Seite weiterleiten, die das Formular gar nicht zeigt. So macht es zum Beispiel die Forensoftware von P3D hier. Oder:
  3. Überprüfen ob vielliecht der letzte Eintrag genau der selbe ist, wie der, der gerade erneut gesendet wird und dann eben nicht in die Datei/Datenbank schreiben. Oder:
  4. Mit einer Session verschiedene Bedingungen überprüfen, z.B. wann der letzte Post gemacht wurde und dementsprechend schreiben lassen oder nicht.
  5. ...

Ansätze dafür gibt es viele. Sei kreativ, denk dir ne Lösung aus und setze sie um.

Bye
Phil
 
Zuletzt bearbeitet:
[*]Überprüfen ob vielliecht der letzte Eintrag genau der selbe ist, wie der, der gerade erneut gesendet wird und dann eben nicht in die Datei/Datenbank schreiben. Oder:
Das hatte ich mir auch gedacht nur bin ich leider nicht fähig, dass umzusetzen. *noahnung*
 
Ich denke Phils 2. Vorschlag ist der einfachste.

Du hast ja sicherlich nen Link auf das PHP-Skript, wo es einfach nur angezeigt wird. Wenn du nach dem hinzufügen eines Eintrages mit

header("Location: shoutbox.php?mode=show");​

bzw. einem entsprechenden Link arbeitest sollte es gehen.
 
Eine ganz banale Lösung, die ich mir vor Jahren mal überlegt habe, auf die bestimmt andere auch schon gekommen sind:
In der Session wird eine Variable abgelegt, anhand der man feststellen kann, ob das Formular gespeichert werden darf. Im Code, der das Eingabeformular darstellt, machst Du sinngemäß Folgendes:
PHP:
<?php
// Counter anlegen
if ( !isset($_SESSION["writeCounter"]) ) {
    $_SESSION["writeCounter"] = 0;
}
$_SESSION["writeCounter"]++;
?>
<input type="hidden" name="writeCounter" value="<?php echo $_SESSION["writeCounter"];?>" />

Das input-Feld muss in Dein Formular mit rein. Der Code, der dann die Seite auswertet und abspeichert, sieht dann etwa so aus:

PHP:
<?php
// Nur abspeichern, wenn Counter identisch
if ( $_SESSION["writeCounter"] == $_REQUEST["writeCounter"] ) {
    // Formularbeitrag speichern
    /* vorhandenen Code einsetzen */
    // Counter erhöhen, damit beim nächsten Aufruf die Werte nicht mehr
    // zusammenpassen und das Formular nicht nochmal gespeichert wird.
    $_SESSION["writeCounter"]++;
}
?>

Das Ganze sorgt dafür, dass nur einmal das Formular gespeichert wird. Der Code ist jetzt mal nur so auf die Schnelle hingeschrieben, ich denke aber, dass man die Grundidee daraus erkennen kann.

Mit dieser Lösung braucht man keine merkwürdigen Mechanismen, die auf Client-Seite sichtbar werden, wie es z.B. beim Redirect der Fall ist.
 
Ich kann PHP nicht also habe ich auch keinen Ansatz. Habe das Script so ausm Netz und es funktioniert ja auch soweit mal abgesehen eben von dem beschriebenem Problem.

@Rones
Habe den Code jetzt mal so geändert wie ich dachte, dass du es meinst . Rausgekommen ist
Code:
<HTML><HEAD><TITLE>.. www.der-gott.de</TITLE>
<style type="text/css">
<!--
A:link  {text-decoration:none; border-bottom: 1px dotted; color: #000000; }
A:visited {text-decoration:none; border-bottom: 1px dotted;  color:#000000; }
A:hover {color:#ffcc00;  text-decoration: underline; }
a:visited:hover {text-decoration:none; border-bottom: 1px solid; color: #ffcc00; }-->
input{font: 7px Verdana color: #000000; border: 1px solid #000000}
.button{border:1px solid #000000;color:#000000;background:#DDDDDD;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:9px;}
.textfeld{border:1px solid #000000; color:#000000;background:#DDDDDD;font-family:Verdana,Arial,Helvetica,sans-serif;font-size:9px;}
body      { 
font-family:verdana;
font-size:7pt;
color="#000000" 
}
-->
</style>
<META content="NOTEPAD" name=GENERATOR>
</HEAD>
<BODY  bgcolor="#FFFFFF" border="0" bgproperties="fixed"><center><table width=135>
<font face="Geneva,Verdana,Arial,Helvetica,Geneva" style="font-size:6px;">
<?
$person = str_replace ("\n"," ", $person);
$person = str_replace ("<", " ", $person);
$person = str_replace (">", " ", $person);
$person = stripslashes ($person);
?>
<form action="msg.php" method="post">
 <table>
	<tr>
		<td><font face="Verdana" size="1,5"><b>Nick:</b></td>
		<td><input type="text" name="person" class=textfeld size="20" maxlength="20" value="<? echo $person; ?>"><br></td>
	</tr>
	<tr>
               	<td><font face="Verdana" size="1,5"><b>Message:</b></td>
		<td><input type="text" name="message" class=textfeld size="20" maxlength="90"><br></td>
	</tr>
	<tr>
		<td></td>
		<td><input type="submit" value="hinschreiben" class=button></td>
	</tr>

</table>

</form>
<?php


$message = $_POST["message"];
$person = $_POST["person"]; 
$chat_file_ok = "msg.txt";
$chat_lenght = 15;
$max_single_msg_lenght = 1024;
$max_file_size = $chat_lenght * $max_single_msg_lenght;
$file_size= filesize($chat_file_ok);            
if ($file_size > $max_file_size) {
$lines = file($chat_file_ok);    
$a = count($lines);
$u = $a - $chat_lenght;
for($i = $a; $i >= $u ;$i--){
        $msg_old =  $lines[$i] . $msg_old;
    }
$deleted = unlink($chat_file_ok);
$fp = fopen($chat_file_ok, "a+");
$fw = fwrite($fp, $msg_old);
fclose($fp);
}
$msg = str_replace ("\n"," ", $message);
$msg = str_replace ("\n"," ", $message);
$msg = str_replace ("<", " ", $msg);
$msg = str_replace (">", " ", $msg);
$msg = stripslashes ($msg);
if ($msg != ""){
$fp = fopen($chat_file_ok, "a+");
$fw = fwrite($fp, "\n<b>$person :</b> $msg");
fclose($fp);
}
$lines = file($chat_file_ok);
$a = count($lines);
$u = $a - $chat_lenght;
for($i = $a; $i >= $u ;$i--){
        echo $lines[$i] . "<br>";
    }
f ( $_SESSION["writeCounter"] == $_REQUEST["writeCounter"] ) {
if ( !isset($_SESSION["writeCounter"]) ) {
    $_SESSION["writeCounter"] = 0;
}
$_SESSION["writeCounter"]++;
?>
<input type="hidden" name="writeCounter" value="<?php echo $_SESSION["writeCounter"];?>" 

$_SESSION["writeCounter"]++;
}

?>


</table>
</BODY>
</HTML>

Funktionieren tut es aber immer noch nicht weshabl ich davon ausgehen muss, dass ich einen Fehler gemacht habe. Würdest du mir vielleicht verraten wo der Fehler liegt =) ?
 
Ich hab jetzt die comments oben nicht gelesen.
Aber ich hätte das jetzt ganz einfach so gemacht.

Du überprüfst ganz einfach vor dem eintragen des posts in die mysql datenbank
ob der name mit dem eintrag schon existiert.
Wenn ja dann soll ers nicht eintragen, wenn nein soll ers eintragen. Fertig!

machs so

PHP:
$result = mysql_query("SELECT * FROM shoutbox WHERE name = '".$name."' AND einrag = '".$eintrag:"'");

danach

PHP:
if (mysql_num_rows($result1)>0) 
 {
  //hier nichts machen
 }
else
 {
  //Den shoutbox eintrag in der mysql abspeichern :)
 }


So Far !
 
Zurück
Oben Unten