Einfache Eingabeformulare mit Exportierfunktion (.txt)

Sldr

Grünschnabel
Hallo,

ich bin absoluter Anfänger was Web- bzw. Datenbank-Programmierung betrifft. Für ein studentisches Projekt ist es erforderlich, dass ich eine Art browserbasierte Umfrage ausarbeite (ist nur ein sehr kleiner Teil der Arbeit und soll ohne große Extras sein). Dies steht im Zusammenhang mit einem Hörversuchs-Design.

Soll-Funktionen: Die Probanden bekommen nacheinander Formulare präsentiert, die sich "nur" in der im Hintergrund abgespielten Audio-Datei und einem Piktogramm unterscheiden, d.h. die Bewertungskriterien sind identisch. Um die Komplexität zu begrenzen wäre es ausreichend, wenn für jedes Formular eine eigene Textdatei erstellt wird. Außerdem möchte ich mich auf HTML und PHP beschränken.

Bisheriger Ansatz:
PHP:
Formular:
<html>

<form method='POST' action='PHP.php'>

<INPUT type="radio" name="Var1" value="-2"><INPUT type="radio" name="Var1" value="0"><INPUT type="radio" name="Var1" value="1">
<INPUT type="radio" name="Var2" value="-2"><INPUT type="radio" name="Var2" value="0"><INPUT type="radio" name="Var2" value="1">

<INPUT type="submit" value="speichern">

</form>

</html>
und:
PHP:
Auswertung:
<html>

<?php
    $alle_angaben = "Var1: " . $_POST['Var1'] ."\r\n" . "Var2: " . $_POST['Var2'];
    $datei = fopen("daten.txt","w");
    fwrite($datei, $alle_angaben);
    fclose($datei);
?>

</html>

Dies funktioniert soweit. Einige Optimierungsmöglichkeiten stehen allerdings noch aus:
- Nach dem Ausfüllen eines Formulars soll beim Abschicken direkt auf das nächste Formular gelinkt werden. Ist es möglich, die 2 einzelnen Dateien (Formular.html UND Auswertung.php) in eine zusammenzufassen und direkt das nächste, fast identische Formular aufzurufen?
- Wie "definiere" ich optionale Angaben? Nicht alle Fragen sollen Pflichtangaben sein und in der Textdatei sollen alle Daten richtig zugewiesen sein. Dies funktioniert zwar, allerdings bekomme ich (beim Auslassen eines Feldes) eine Fehlermeldung im Browser ("Undefined index").

Ich denke, dies sind die größten Schwierigkeiten momentan und da die Zeit ein bisschen eilt, kann ich mich leider nicht so in die Materie hineinarbeiten. Ich hoffe, ihr könnt mir "einfache" Lösungen geben und bedanke mich schonmal dafür. Falls dieser Post nicht in diese Rubrik gehören sollte oder diese Fragen schon zur Genüge behandelt sein sollten, bitte ich um Entschuldigung.
 
Hi,
ich weiß nicht ob das jetzt nur hierfür verkürzt wurde oder ob Du ein Fehler gemacht hast, aber in deiner HTML-Datei fehlt das ganze htmlgerüst wie doctype, head, body etc.
Des Weiteren benötigst Du in einer PHP-Datei kein HTML-Gerüst, es ist sogar eher problematisch.

Um Dein Problem mit der Fehlerausgabe in den Griff zu bekommen solltest Du Deine $_POST variablen darauf überprüfen ob diese gesetzt wurden (isset() und !empty()).
Das geht am kürzesten mit einem Ternary Operator:
PHP:
    $var1 = 'Var1:' . (isset($_POST['Var1'])    ? $_POST['Var1'] : '');
    $var2 = 'Var2:' . (isset($_POST['Var2'])   ? $_POST['Var2'] : '');
Und Du solltest das schreiben in die Datei mit einer Fehlerüberprüfung (Exception-Handling) versehen:
PHP:
try {
      $var1 = 'Var1:' . (isset($_POST['Var1'])    ? $_POST['Var1'] : '');
      $var2 = 'Var2:' . (isset($_POST['Var2'])   ? $_POST['Var2'] : '');

      $fileName = './daten.txt';
      $alle_angaben = $var1 . "\r\n" . $;

      if ( !file_exists($fileName) ) {
        throw new Exception('Datei nicht gefunden.');
      }

      $fp = fopen($fileName, 'a'); //Dateizeiger wird am Ende angesetzt
      if ( !$fp ) {
        throw new Exception('Datei konnte nicht geöffnet werden!');
      }
      fwrite($fp, $alle_angaben);
      fclose($fp);

      header('Location: ./nextform.php');

    } catch ( Exception $e ) {
      echo 'Exception abgefangen: ',  $e->getMessage(), '\n';// send error message if you can
    }

Wenn Du das Action im Form entfernst und das drücken des Submit-Buttons abfragst kannst Du das PHP auch direkt in die HTML, bzw. umgekehrt, reinschreiben.

Und Du solltest Variablen nicht Va1 oder so nennen. benenn diese besser so das auch Menschen diese lesen können. Dann kannst Du auch später noch leichter Deinen eigenen Code lesen, hierbei sind auch Kommentare hilfreich.

Ich habe Die mal ein kleines Testbeispiel mit drei Dateien welche nacheinander geladen werden angehängt.
Das Beispiel habe ich mal schnell noch mit Bootstrap aufgehübscht.

Viele Grüße
 

Anhänge

  • filesave.zip
    3,9 KB · Aufrufe: 1
Hi,
kannst Du mir mal erklären wie das mit dem XSS über den Dateinamen funktioniert?
Und eigentlich hätte ich auf die $var1 und $var2 mit htmlentities() und strip_tags() versehen müssen.
Denn ich könnte doch auch den Value der Radiobuttons verändern. Oder?
Ich bin jetzt ehrlich immer etwas unsicher mit dem doofen XSS.

Grüße
 
Hi Jan-Frederik,

vielen Dank für deine Antwort und das ausgearbeitete Beispiel. Es waren ein paar sehr entscheidende Hinweise dabei, die mich meinem Ziel näher bringen konnten. Reverse-Engineering :)

Für die Pflichtfeldangabe habe ich das "Required"-Attribut implementiert, welches super funktioniert.
 
Und eigentlich hätte ich auf die $var1 und $var2 mit htmlentities() und strip_tags() versehen müssen.
Nein, das wäre unnötig gewesen und m. E. sogar falsch. Du gibst die Variableninhalte ja nur in eine *.txt-Datei aus, die hoffentlich niemand als HTML-Datei öffnen wird. Es ist immer eine Frage des Kontexts, in dem die Daten weiterverarbeitet werden, um zu entscheiden, ob Maskierung notwendig ist.

kannst Du mir mal erklären wie das mit dem XSS über den Dateinamen funktioniert?
Oh, das stimmt doch nicht. Ich hatte mich verlesen und gedacht, dass du den Dateinamen aus den $_POST-Variablen zusammenbaust. Falls nun dieser Dateiname ungültig ist und die Exception Nachricht zufällig den Dateinamen roh wiedergibt (falls PHP so programmiert ist), dann könnte HTML aus $_POST als HTML in der PHP-Ausgabe landen (= XSS).

Für die Pflichtfeldangabe habe ich das "Required"-Attribut implementiert, welches super funktioniert.
Beachte, dass man das sehr leicht umgehen kann. Clientseitige Validierung darf niemals der Sicherheit dienen.
 
Hallo,

Danke für die weiteren Anmerkungen. Ich hatte vergessen zu erwähnen, dass ich die Formular-Abfragen auf einem lokalen Server ausführen lassen möchte. Eine möglichst simple und für mich nachvollziehbare Gesamtstruktur sowie die Gewährleistung der Funktionalität haben unter dem zeitlichen Aspekt Priorität. Den Probanden wird nur eine Mouse zur Verfügung stehen und der Vollbildmodus wird aktiviert. Sind die Einbußen bei der Sicherheit unter diesen Umständen vernachlässigbar oder muss ich mit gravierenden Mängeln/Risiken bei der Durchführung rechnen?

Was sollte ich bei dem Html-Gerüst beachten? (von Jan-Frederik angesprochen)

Danke sehr
 
Hi,
also ich glaube kaum das wenn Du das in einer kontrollierbaren Umgebung ausführst probleme mit einem Hacker bekommst und wenn diesem dann noch nichtmal eine Tastatur zur Verfügung steht …

Was sollte ich bei dem Html-Gerüst beachten?
nun das es dem Minimalstandard entspricht. Also:

HTML:
<!DOCTYPE html>
<html>
  <head>
    <title></title>
  </head>
  <body>

  </body>
</html>

Nur <html> außen herum reicht nicht aus.

Grüße
 
Zurück