Ankündigung

Einklappen
Keine Ankündigung bisher.

Affenformular / Doppelpost / Weiterleitung

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Affenformular / Doppelpost / Weiterleitung

    Hallo Zusammen!

    Ich entwickle gerade ein Gästebuch, und verwende dafür ein Affenformular.
    Die Seite ist folgendermaßen aufgebaut:

    index.php

    PHP-Code:
    <html>htmlcode für headermenüs etc.

    include(
    'content.php');

    htmlcode für footer etc.
    </
    html
    in der content.php werte ich dann die variable do aus:
    PHP-Code:
    ...
    switch(
    $do) {
    case 
    'gb':
    include(
    'gb.php');
    break;
    ... 
    gb.php:
    PHP-Code:
    if (isset($_POST["text"])) {
     
    plausibilisierung;
     
    eintrag in db schreiben;

    header('Location: index.php?do=gb&ok=1');

    }

    if (isset(
    $_GET["ok"])) {
     echo (
    "Vielen Dank für Ihren Eintrag!");

    Standardmässig wird das Formular in aus der gb.php (hab ich jetzt nicht in den QC eingebaut) angezeigt.
    Tritt bei der plausibilisierung ein Fehler auf, werden die Boxen rot umrandet (wenn z.B. der Name vergessen wurde).

    Damit der Eintrag bei einer aktualisierung nicht 2x oder öfters erstellt wird arbeite ich mit der Modifikation des Headers.
    Und genau hier liegt das Problem:

    Da ich ja in der index.php bereits HTML code ausgebe und erst später die content.php includiere erhalte ich die Fehlermeldung, dass der Header nicht mehr modifiziert werden kann, da er bereits gesendet wurde.

    Hat jemand eine elegante Lösung?

    Was ich mir bisher selbst überlegt hätte:
    • ein ob_start(); zu Beginn der index.html; das funktioniert, allerdings habe ich gehört, dass dadurch die Seite langsamer wird!? Und da ich eine performante Seite (viele User werden sich einloggen etc.) bauen will, wäre das nicht das Richtige
    • ich könnte beim absenden des formulars eine eigene gbpost.php aufrufen in der ich keinen HTML Code ausgebe, sondern nur prüfe ob der Eintrag erstellt wurde, und ggf. weiterleite (mit header(Location...)); allerdings hat dies zum Nachteil dass ich die Fehlermeldungen wieder an die index.php übertragen müsste und diese dann auswerten müsste (in der gb.php)
    • Ein SELECT an die DB schicken und prüfen ob genau dieser Eintrag schon vorhanden ist. Gefällt mir aber persönlich nicht soo gut

    Danke für Eure Hilfe!

    Grüße
    Malungo

  • #2
    Wie wärs mit so was:
    PHP-Code:
    if (isset($_POST["text"])) {
     
    // plausibilisierung;
     // eintrag in db schreiben;

     
    echo 'danke für Ihren Eintrag';
    } else {
      
    // Formular zum Eintragen ausgeben

    Kommentar


    • #3
      Hi Wolla!

      Genau das will ich doch vermeiden.
      Wenn ich im Browser F5 drücke wird der Eintrag nochmal gepostet!

      Grüße
      Malungo

      Kommentar


      • #4
        willst du vermeiden das genau der gleiche Post kein 2. mal in dein GB gelangt?

        Du könntest einen hash der Nachricht in $_SESSION ablegen und bei Eintrag prüfen ob der gleiche Hash schon vorhanden ist.

        Dann könntest du gleiche Posts vermeiden, aber sobald sich ein Zeichen im Post ändert wäre das auch schon wieder hinfällig.

        Kommentar


        • #5
          genau das will ich vermeiden!!

          Stimmt, das mitn Hash könnte man auch machen; aber da sich der Hash bei einem anderen Zeichen schon ändert ists wohl nicht DIE Lösung...

          Am Besten gefällt mir das mit dem header('Location ...')
          Allerdings funzt das nicht, weil der Header wg. der index.php ja schon gesendet wurde

          Kommentar


          • #6
            Wenn die Seite aktualisiert wird ( z.B. mittels F5 ), wird ja kein Zeichen in dem Post verändert. Somit könntest du die Lösung von moveax doch benutzen.

            Kommentar


            • #7
              Ich benutze auch einen Hash - eine Kopie ins input Feld,die andere in die Session. Bei jedem Request neu erzeugen.

              Kommentar


              • #8
                noch eine möglichkeit wäre es über refresh zu machen:
                gb.php
                PHP-Code:
                $refresh false;
                if (isset(
                $_POST["text"])) {
                 
                plausibilisierung;
                 
                eintrag in db schreiben;
                 
                $refresh true;
                }

                if (isset(
                $_GET["ok"])) {
                 echo (
                "Vielen Dank für Ihren Eintrag!");

                PHP-Code:
                <head>
                <?php
                if($refresh) {
                  echo 
                '<meta http-equiv="refresh" content="0" URL="index.php?do=gb&ok=1">';
                }
                ?>
                </head>

                Kommentar


                • #9
                  Man könnte das Problem auch lösen indem Zeiten mit einander vergleicht.
                  Man legt die Zeit des letzten Aufrufs in die Session und vergleicht dann die Zeiten. Sollten beide Zeiten die selbe sein, so ist es ein doppel Post. Ich hoffe das ist verständlich.

                  PHP-Code:
                  <?
                  if(isset($_GET['time'])) {
                      if($_SESSION['lastposttime'] == $_GET['time']) {
                          unset($_POST);
                      } else {
                           $_SESSION['lastposttime'] = $_GET['time'];
                      }
                  }


                  echo '<form method="post" action="formular.php?time=' . time() . '">';
                  // Formular

                  ?>
                  schönen tag noch
                  Felix

                  Kommentar


                  • #10
                    Ok, danke für die vielen Lösungsvorschläge!
                    Für das GB würde das funktionieren!

                    Ich würde halt gerne mit der header-Methode arbeiten, da ich ein ähnliches Problem später beim Posten einer Nachricht im Forum habe.

                    Posten dürfen nur eingeloggte Benutzer, im posting skript welches ebenfalls über die content.php inkludiert wird muss ich prüfen ob der User eingeloggt ist, wenn nicht soll er zum login weitergeleitet werden.

                    Wie funktioniert das Ganze hier im Forum?
                    Wenn ich auf Antworten klicke und nicht eingeloggt bin, komme ich ja auch zur anmeldemaske...anschl. (nach erfolgreichem login) werde ich zu "Auf Thema antworten" weitergeleitet...
                    Geht das nicht mit der Modifikation des Headers?

                    Kommentar


                    • #11
                      Es gibt da ne sehr nette Klasse zur verhinderung von Formular Reload.

                      PHP-Code:
                      class formreload 
                          
                      {
                          var 
                      $tokenarray '__token';
                          var 
                      $tokenname '__token';
                          function 
                      get_formtoken() 
                              {
                              
                      $tok md5(uniqid("foobarmagic"));
                              return 
                      sprintf("<input type='hidden' name='%s' value='%s'>",$this->tokenname,htmlspecialchars($tok));
                              }
                          
                          function 
                      easycheck() 
                              {
                              
                      $tok $_POST[$this->tokenname];
                              if (isset(
                      $_SESSION[$this->tokenarray][$tok])) 
                                  {
                                  return 
                      false;
                                  } 
                              else 
                                  {
                                  
                      $_SESSION[$this->tokenarray][$tok] = true;
                                  return 
                      true;
                                  }
                              }
                          } 
                      und dann

                      PHP-Code:
                      $f =& new formreload;

                      if (isset(
                      $_POST['send']))
                              {
                              if (
                      $f->easycheck()) 
                                  {
                                  
                      // Hier wird verarbeitet.
                                  
                      }
                              else 
                                  {
                                  print 
                      "Fehlermeldung";
                                  }
                              } 

                      Kommentar


                      • #12
                        Danke @Jego
                        Diese Lösung hört sich super an!!! Die werde ich ich verwenden.

                        Somit wär das 1. Problem gelöst.

                        Aber wie gehe ich das Problem an, dass bestimmte Contentinhalte nur von registrierten Benutzer angezeigt werden dürfen?

                        aktuell sieht z.B. die Datei bestellung.php so aus:

                        PHP-Code:
                        include('check_user.php');
                        //Ausgabe contentinhalt 
                        check_user.php
                        PHP-Code:
                        if (!isset($_SESSION['userid'])) {
                        header('Location: urlzumanmeldeformular');

                        Hätte das als sehr schöne Lösung empfunden, da ich dann nur in die Contentfiles, die nur für registrierte Benutzer sichtbar sein sollten das include check_user eingefügen hätte müssen.

                        Header kann ich aber nicht senden, da in der index.php schon HTML-Ausgaben stattgefunden haben.

                        Kommentar


                        • #13
                          dann mach doch

                          PHP-Code:
                          if (!isset($_SESSION['userid'])) {
                          die(
                          "<script type=\"text/javascript\">window.location.href = 'urlzumanmeldeformular';</script>");

                          Kommentar


                          • #14
                            Solche Fragen verstehe ich immer nicht. Was hindert einen denn daran, die ganzen Scriptsachen vor den Ausgabe auszuführen? Dann klappts auch mit header (); exit;

                            Kommentar


                            • #15
                              @nikosch
                              Das geht nicht, da die Seite so aufgebaut ist, wie mein 1. Post zeigt:

                              index.php -> HTML Code
                              irgendwo darin inkludiere ich die content.php welche wiederum die bestellung.php inkludiert.
                              Sobald ich in der bestellung.php bin wurde schon HTML Code ausgegeben; d.h. der header kann nicht mehr modifiziert werden .

                              ein ob_start(); zu beginn der index.php löst das Problem (temporär?)
                              Hab nämlich gehört, dass dadurch die Performance sinken soll!
                              Und da das evtl. mal ne Seite mit vielen Usern/Aktionen wird will ich sie von Grund auf "richtig" aufbauen.

                              Kommentar

                              Lädt...
                              X