PHP Page-Reload: Variablen leeren vor HTML-Submit

cumulonimbus8

Fleet Admiral
Registriert
Apr. 2012
Beiträge
18.400
Moin!

Mich wurmt da etwas… Per PHP (leidlich blutiger Anfänger) möchte ich eine Eingabe (HTML, FORM-Tag, Input-Type:Text, getriggert mit Input-Type Submit) auffangen und in eine Datei schreiben.
Hier mein Machewerk:
HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>PHP-Info</title>
</head>
<body>
<br>
Seite abgerufen am <?php echo ( date('d.m.Y \u\m H:i:s') );?> Uhr.
<br><br>
<?php
if ((isset($_POST['eingabe1'])) or (isset($_POST['eingabe2']))) {
echo '
<script type="text/javascript">
//location.reload();
</script>';
}?>

<form action="" method="post">
 Eingabe 1: <input type="text" name="eingabe1" id="eingabe1" onkeydown="if (event.keyCode == 13) {return false;}">
 <br>
 Eingabe 2: <input type="text" name="eingabe2" id="eingabe2" onkeydown="if (event.keyCode == 13) {return false;}">
 <br>
 <input type="submit" value="Speichern">
</form>

<?php
echo ("P1=" . $_POST['eingabe1'] . " - P2=" . $_POST['eingabe2']);
if (($_POST['eingabe1'] != "") and ($_POST['eingabe2'] != "")) {
 $Eingabe = trim($_POST['eingabe1']) . " | " . trim($_POST['eingabe2']);
 $Text = "Seite abgerufen am " . date('d.m.Y \u\m H:i:s') . "\n";
 $Text = $Text . $Eingabe . "\n\n";
 $DateiName = "test.txt";
 $FSO = fopen($DateiName , "a+");
 fwrite($FSO , $Text);
 fclose($FSO);
} else {
 //
}
?>
</body>
</html>
Das funktioniert auch grundsätzlich. Und es enthält neben der Zeit-Meldung zum Sehen zwei Eingabefelder, auch nur zum Üben.

Das Problem
Um das zu testen (meint: Codeänderungen) halte ich die Datei (auf XAMPP laufend) im Browser offen.
Nicht, dass mich Chrome nervt immer wieder nach F5 nervt das File zwecks Formular-Übertragung zu bestätigen - ich scheitere an der Tatsache, dass PHP die Variablen (d.h. das $_POST Array) gefüllt hält.

Wie überrede ich PHP nach F5 diese Variable(n) zu leeren, einerseits, sie aber andererseits nach dem Auslösen von FORM bei diesem (jeweiligen) Durchgang als wiedergefüllt anzunehmen?
UnSet löscht das Array und ich bekomme es nicht wiederbelebt, allein jedes Array-Feld auf leer zu setzen behält es ebenfalls leer. Klar kann ich durch Eingaben das Array ändern (ohne F5 - und ohne jedes Leeren), aber 1x F5 und es wird der alte Inhalt ins File geschrieben.

CN8
 
Gar nicht, PHP ist Serverside. Dein "Fehler" beim Client.

PHP kann sich selber erstmal gar nichts speichern, denke also dein Client schickt die Daten immer neu.
 
  • Gefällt mir
Reaktionen: Nase
Das ist weniger Sache von Client oder Server als ein architektonisches Problem.

Forms gehen an einen Prozessor. Das ist NICHT die Seite mit dem Formular.

form.php => process.php => Ausgabe.php

form hat das Formular und schickt es ab(Client).
process nimmt die Daten an und verarbeitet sie (Server).
ausgabe wird vom Server als Bestätigung generiert. Hier kommen evtl aufgetretene Warnungen hin. Ausgabe kann aber auch das Formular nochmal sein. Wichtig ist aber eine Trennung der Prozeßlogik.

Dabei wird ganz “automatisch” der Inhalt der Post-Daten verworfen.
 
  • Gefällt mir
Reaktionen: Nase
Da kann ich nicht ganz folgen und zustimmen - und ich denke sogar aus gutem Grund.

Unstreitig ist was FORM tut. PHP indes sollte (im Falle der Methode Post) $_POST als Array die Rückgaben (sagen wir vereifacht: des Browsers) beim Submit auffagen.
Exakt das tut die Mechanik. Ich kann, einmal die Datei geladen, immer wieder Eingaben machen die sich in der Text-Datei wiederfinden.
Bis hierhin also keine Probleme.

Nun aber - im Zuge des Herumprobierens - drücke ich F5 (allseits bekannt als Page-Reload) und der Mechanismus schreibt prompt die letzten »Eingaben«, genauer die Inhalte von $_POST[…], in die Datei. Wiederholbar. Gebe ich neu ein ersetzen die die alten Eingaben, aber am F5-Problem ändert sich nichts.

Was ich will ist, dass die Seite einfach (neu) lädt und die $_POST[…] leer sind, mithin das IF nicht einfach so auslöst, nach Eingabe und Submit sich indes eine Füllung (so denn ein–gegeben) einstellt die wiederum nun das IF auslöst…
→ offenbar die Schwachstelle im System
…und dann schreibt oder nicht. Mir fehlt da also eine Initialisierung nach F5. Geht so was?
Woher - Gegenfrage - soll der Browser denn etwas nehmen was noch nicht submittet wurde, nach F5? Warum bleiben die Variablen (sämtlicher Art) denn also am Leben?

CN8
 
Wenn ich eine Webseite wirklich vollständig refreshen will, drücke ich nicht F5, sondern immer Strg + R.

Denn soweit ich weiß, wird bei F5 der Cache weiterverwendet.
 
F5 schickt die Formulardaten nochmal ab. Du aktualisierst ja nicht die Seite im Urzustand, sondern den bereits zweiten Aufruf mit den POST Daten.
Verhindern kannst du das z.B. indem du dein PHP auf zwei Seiten aufteilst. Das Formular sendet die Daten an ein PHP Skript. Dieses verarbeitet die Daten und leitet dann wieder zurück auf das Formular.
 
Wenn ich eine Webseite wirklich vollständig refreshen will, drücke ich nicht F5, sondern immer Strg + R.
OK, klingt logisch. Sollte ich bei meinen Tests wohl künftig verwenden. Ich bin mir nur nicht sicher ob und inwieweit F5 und ein Reolad-Icon dies oder das Andere tun (siehe auch Shift+F5) und was ein profaner Anwender tut.

F5 schickt die Formulardaten nochmal ab.
Warum..?! Ein Reload ist nach meinem dummen Verständnis zwar auch die Verwendung des Caches, aber warum es Formulardaten (..!) erneut absendet (..!!) ist mir ehrlich unbegreiflich solange ich nicht auf jener Seite etwas triggere.
Ich glaube ich bin zu blöd für diese Welt… Logisch ist für mich nämlich was Anderes.


Belassen wir es dabei; es ging mir hier nur um meine eigene Bequemlichkeit beim Testen. Eventuelle Normalbenutzer lass ich einfach außen vor. Vornehmlich, da ich eben bei Recherchen auf die Frage stieß Inhalte beim Re-… …load zu erhalten statt leere Felder vorzufinden. Das ist en gros konträr zu meinem Problem und nicht minder logisch wie unlogisch.

CN8
 
Ist doch logisch: Wenn du das Formular zum ersten Mal aufrufst sind noch keine POST Daten vorhanden. Sendest du es ab, dann leitet dein Formular auf die gleiche Seite weiter, nur diesmal inkl. POST Daten. Wenn du jetzt reload drückst, aktualisierst du die Version mit den POST Daten.
Nach absenden des Formulars befindest du dich zwar auf der gleichen Seite, aber einer anderen Version davon.
 
Vermutlich wird es verständlicher, wenn man weiß, das da im Hintergrund beim "Neu laden" passiert: Es wird er letzte Request nochmal gesendet.
Wenn du ein Formular abgesendet hast (POST), wird das nach F5 eben nochmal gesendet. Logisch, oder?

Wie Sparta schon angedeutet hat, gehen daher die schlauen Webdesigner hin und machen nach dem POST-Request eine GET-Weiterleitung, so dass der Browser bei F5 eben diesen GET-Request macht, anstatt die Formulardaten nochmal per POST zu senden.

Andarkan schrieb:
Wenn ich eine Webseite wirklich vollständig refreshen will, drücke ich nicht F5, sondern immer Strg + R.
Blöd nur, dass F5 und STRG+R identisch sind. Was du meinst ist STRG+SHIFT+R, das ist identisch zu STRG+F5. (Zumindest was den Firefox angeht. STRG+F5 mach meines Wissens nach in allen Browsern das selbe, daher bevorzuge ich das)
 
Ein doofer Programmierer wie ich hängt in der Denkschleife, dass ein Restart alle Variablen initialisiert.
Nach welcher Logik mit POST erfasste Daten gespeichert bleiben entzieht sich mir, da hat der Begriff ReLoad irgendwo seine Berechtigung verloren.
→ Ebenso wieso mit PHP geleerte [nicht mal gelöschte] von POST abhäbngige Array nicht wieder per POST & Triggern hic et nunc gefüllt werden.
Ergo eine Frage von Denkkonzepten…

CN8
 
Browser funktionieren nun mal so, dass kannst du dir noch so schöndenken wie du willst. Das Problem und Workaround sind ja bekannt. Ob und wie du das umsetzt ist dir überlassen.
cumulonimbus8 schrieb:
Ebenso wieso mit PHP geleerte [nicht mal gelöschte] von POST abhäbngige Array nicht wieder per POST & Triggern hic et nunc gefüllt werden.
Den Satz verstehe ich nicht. Ob und wie $_GET und $_POST gefüllt werden hängt vom Request ab. Was du mit denen dann machst hat keinen Einfluss auf zukünftige Anfragen. Wenn dein Script fertig ist, werden die automatisch gelöscht.
 
Forms sind aber nicht statusfrei. Ich klick auf Send und im Hintergrund gibts
HTTP:
 GET /formaction.php?f1=v1&f2=v2 ...
Auf diese Seite wird gewechselt. Formaction.php wird generiert auf Basis von $_REQUEST[]. Dessen Inhalt geht mit Ende der Ausführung auf dem Server verloren.

Refresh, egal wie, sendet die Anforderung erneut und übergibt wieder dieselben Parameter, egal ob das per GET war oder per POST. $_REQUEST[] wird neu erstellt und die Seite unter Verwendung derselben Parameter neu generiert— mit Cache ist da gar nichts, außer man setzt bewußt fragwürdige Header.
Leicht nachstellbar, indem man irgendwo ein random() einbaut.

Umgehen kann man das, indem man den Request mit den Formdaten vor dem Anwender versteckt. Dafür gibts form action=... und zB Ajax. In beiden Fällen wird eine neue Anforderung gestartet, entweder synchron oder asynchron, die nicht in der Browserhistory auftaucht und damit auch nicht per F5 oä erreichbar ist.

Sobald man aber hergeht und form action=<self> verwendet und Input = process = output hat, hat man immer das “Repost”Problem.
 
Gut, Danke.
Aber die Logik der Logik leuchtet mir trotzdem nicht ein… ;)

CN8
 
Zurück
Oben