Ben: Nach Weiterleitung trotzdem auf $_POST zugreifen?

Hallo,

ich habe ein kleines Denkproblem mit einem Bestellvorgang für meine typeworX-Homepage. Ich möchte z.B. Schreibarbeiten über mehrere Teilformulare bestellen lassen können. Ich habe das bislang so gemacht, dass ich auf jeder Seite auf $_POST zugreife und die entsprechenden Daten wieder in hidden-inputs schreibe. Klappt soweit auch alles reibungslos. Mein Problem kommt jetzt dadurch, dass der User entscheiden können soll, ob er nötige Unterlagen per Post mitschicken oder als eMail-Anhang versenden möchte. Ich habe das jetzt so gelöst, dass ich je nach dem, welche Möglichkeit gewählt wurde einen Header mit einer Location sende. Das Problem ist jetzt natürlich, dass dadurch die ganzen vorigen Variablen verloren gehen. :-(

Ich habe überlegt, dass ich vielleicht vorher die Daten in eine Datenbanktabelle schreibe und dann anhand der IP des Users wieder eintrage bzw. mitsende, aber das ist doch etwas umständlich oder?

Hat jemand einen Rat für mich?

Vielen Dank im Voraus und viele Grüße
Ben

--
Phantasie ist wichtiger als Wissen. - Albert Einstein
  1. Hallo Ben,

    Ich habe das bislang so gemacht, dass ich auf jeder Seite auf $_POST zugreife und die entsprechenden Daten wieder in hidden-inputs schreibe.

    Das ist die ungünstigste Lösung, die du dir ausgesucht hast. Diese Daten sind mit jedem Mal, wo du das Formular erneut abschickst, potenziell unsicher, da völlig ohne Probleme änderbar.

    Ich habe das jetzt so gelöst, dass ich je nach dem, welche Möglichkeit gewählt wurde einen Header mit einer Location sende. Das Problem ist jetzt natürlich, dass dadurch die ganzen vorigen Variablen verloren gehen. :-(

    Du hast 2 Möglichkeiten. Entweder du benutzt $_GET (funktioniert genau wie $_POST, nur eben für per GET übergebene Variablen und deren Werte.
    Die zweite, wesentlich sicherere Variante, mit der du auch o.g. Problem lösen kannst, heißt Sessions. Grob gesagt, werden die Daten, die mit einem Formular übertragen werden, auf dem Server gespeichert und sind nur anhand einer praktisch einmaligen - da mit MD5 verschlüsselten - SessionID zugreifbar. Da liest du dich am besten mal in das Kapitel ein (http://www.php.net/manual/de/ref.session.php).

    Grüße aus Darmstadt,
    Benjamin

    1. Hallo Benjamin (netter Name ;-),

      vielen Dank für deine Antwort. Jedoch verstehe ich gerade nicht ganz, warum GET besser als POST dafür geeignet sein soll...? Ist es nicht so, dass bei GET die Anzahl der Zeichen beschränkt ist und die Daten an die URL angehängt werden oder irre ich mich da gerade?

      Über SessionID's könnte ich es natürlich (sobald ich mich etwas damit vertraut gemacht habe) versuchen zu lösen, ich hielt es jedoch für den Anfang für etwas sehr aufwendig.

      Vielen Dank für den Link. Werde mich da auf jeden Fall mal einlesen (in einem Buch von mir finde ich aber auch etwas zu SessionID's).

      Viele Grüße
      Ben

      --
      Phantasie ist wichtiger als Wissen. - Albert Einstein
      1. Hallo Ben,

        an eine mit Location-Header rausgeschickte Umleitung kann man leider nur Get-Parameter anhängen. Es wird ja nur ein Header gesandt und der HTTP-Body vernachlässigt.

        Die Sach mit den Sessions ist da schon besser. Der (die) Cookie(s) dafür wird/werden auch im Header mitgesandt.

        Du könntest die Daten auch vercrypten, und in einen Cookie verpacken. Nur wenn der user keine Cookies will, dann geht das genausoweinig, wie Sessions mit Cookie. Da musst Du dann aber nicht verzwifeln, dann baust Du Dir Deine Sessions eben selbst mit HTTP-Credentials (Auth 401). Die werden ulkigerweise von den Usern selten ausgeschaltet, obwohl das auch meistens geht.

        --------------------------------------------------------------------------
        Bei der Gelegenheit eine Frage an alle Geckonutzer: Wo kann man dem Viech sagen, dass es JavaScript nur nach Aufforderung nutzen soll? Zum testen ist es verdammt lästig, immer die Einstellungen zu ändern und das Teil neu starten zu müssen.

        Liebe Grüße aus http://www.braunschweig.de

        Tom

        --
        Intelligenz ist die Fähigkeit, aus Fehlern Anderer zu lernen und Mut die, eigene zu machen.
        1. Hi Tom,

          vielen Dank, also werde ich dann wohl doch auf SessionID's zurückgreifen müssen. Gibt es dazu vielleicht
          noch Tutorials und nicht nur die Manual?

          Viele Grüße
          Ben

          --
          Phantasie ist wichtiger als Wissen. - Albert Einstein
          1. Hi Ben,

            Dazu gibt es hier einen ganzen Themenzyklus zwischen Andreas und mir.

            Wenn Du den durch hast, nebst der vielen wichtigen Anmerkungen von Sven, Christian, Christoph, ... *oh jeh, verzeiht bitte*

            dann solltest Du auf jede Schweinerei vorbereitet sein.

            Liebe Grüße aus http://www.braunschweig.de

            Tom

            --
            Intelligenz ist die Fähigkeit, aus Fehlern Anderer zu lernen und Mut die, eigene zu machen.
            1. Hi Tom,

              danke für den Hinweis, werde gleich mal die Forensuche bemühen. Mist, dass die von mir verlangte Druckversion noch
              nicht verfügbar ist, denn "Themenzyklus" klingt ja nach einem halben Roman... *g*

              Viele Grüße
              Ben

              --
              Phantasie ist wichtiger als Wissen. - Albert Einstein
        2. Hi Thomas ;-)

          Sicher ahnst Du es schon...

          Du könntest die Daten auch vercrypten, und in einen Cookie verpacken. Nur wenn der user keine Cookies will, dann geht das genausoweinig, wie Sessions mit Cookie. Da musst Du dann aber nicht verzwifeln, dann baust Du Dir Deine Sessions eben selbst mit HTTP-Credentials (Auth 401). Die werden ulkigerweise von den Usern selten ausgeschaltet, obwohl das auch meistens geht.

          Das ist richtig, nur ist die Frage ob sich das eignet, hier eien HTTP-Authentifzuierung einzubauen? Woher hatt denn der potentielle Kunde seine Zugangsdaten?

          Das ist IMHO ein Beispiel wo man sich auf die URL-Weiterleitung verlassen sollte.

          Grüße
          Andreas

        3. Hi Tom,

          Bei der Gelegenheit eine Frage an alle Geckonutzer: Wo kann man dem Viech sagen, dass es JavaScript nur nach Aufforderung nutzen soll? Zum testen ist es verdammt lästig, immer die Einstellungen zu ändern und das Teil neu starten zu müssen.

          [x] Du suchst nach http://xulplanet.com/downloads/prefbar/

          Fabian

      2. Hallo!

        vielen Dank für deine Antwort. Jedoch verstehe ich gerade nicht ganz, warum GET besser als POST dafür geeignet sein soll...?

        ich auch nicht ;-)

        Ist es nicht so, dass bei GET die Anzahl der Zeichen beschränkt ist und die Daten an die URL angehängt werden oder irre ich mich da gerade?

        Theoretsich nicht, praktisch schon.

        Über SessionID's könnte ich es natürlich (sobald ich mich etwas damit vertraut gemacht habe) versuchen zu lösen, ich hielt es jedoch für den Anfang für etwas sehr aufwendig.

        Ist nicht schwer, das aller simpelste wäre:

        script1.php
        <php
        session_start(); // session starten
        $_SESSION = $_POST; // $_POST-Array in den $_SESSION-Array schreiben($_SESSION wird am Scriptende gespeichert)

        [...]

        // übergeben der SessionID an script2.php als url-parameter
        header("Location: script2.php?".session_name()."=".session_id());

        [...]

        ?>

        script2.php
        <?php
        session_start(); // session starten
        $array_mit_alten_POST_Daten = $_SESSION; // Sessionarray in eigenen Array schreiben, brauchst Du noch nichtmal, kannst auch direkt drauf zugreifen!

        [...]

        // z.B. bei einem Forumlar-Feld "vorname" hieße das dann:
        echo $array_mit_alten_POST_Daten["vorname"];

        [...]

        ?>

        Das heißt Du brauchst nur jeweils 2 neue Zeilen(jeweils die ersten beiden) zusätzlich. IMHO einfacher als mit hidden-Fields!

        Vielen Dank für den Link. Werde mich da auf jeden Fall mal einlesen (in einem Buch von mir finde ich aber auch etwas zu SessionID's).

        Wenn Du Dich in Sessions einarbeitesn möchtest, empfehle ich zusätzlich zu dem verlinkten Manual-Abschnitt noch die FAQ:

        http://www.dclp-faq.de/ch/ch-version4_session.html

        Grüße
        Andreas

        1. Hi Andreas,

          vielen Dank für deine kleine Einführung.

          Also brauche ich auf jeder Seite einfach nur eine neue Session starten, die Daten der letzten Sessiona auslesen und dann alles insgesamt wieder per Header nach dem Absenden an das nächste Formular zu übergeben?

          Scheint ja mit etwas Übung gar nicht so umständlich zu sein, wie ich es mir vorgestellt hatte. :)

          Viele Grüße
          Ben

          --
          Phantasie ist wichtiger als Wissen. - Albert Einstein
          1. Hi Ben!

            Also brauche ich auf jeder Seite einfach nur eine neue Session starten, die Daten der letzten Sessiona auslesen und dann alles insgesamt wieder per Header nach dem Absenden an das nächste Formular zu übergeben?

            Was ich beschreiben habe war der IMHO einfachste Weg das ganze über 2 Seiten zu lösen. bei mehr Seiten würde ich das anders machen.

            Wenn Du z.B. 3 Seiten hast, 1. Adresse, 2. Zahlungswiese, 3. Bestätigung

            dann würde ich auf jeder Seite mit eine Session starten, auf der 2. Seite würde ich die POST-Daten von der 1. Seite mit

            $_SESSION['Adresse'] = $_POST;

            in die Session schreiben, auf der nächten mit

            $_SESSION['Zahlungswiese'] = $_POST;

            und dann im Script welches die Bestellung validiert und ausführt kannst Du auf die Daten der 3. Seite mit $_POST zugreifen, auf die Adresse mit $_SESSION['Adresse'] und auf die Zahlungsweise mit $_SESSION['Zahlungswiese'].

            Die SessionID würde ich immer mit

            header("Location: scriptXY.php?".session_name()."=".session_id());

            übergeben. Also immer für scriptXY.php die nächte Seite angeben, daran wird dann die SessionID als Parameter angehängt, anhand der PHP dann die serverseitig gespeicherten Daten zuweisen kann.

            Scheint ja mit etwas Übung gar nicht so umständlich zu sein, wie ich es mir vorgestellt hatte. :)

            Ist es auch nicht, aber man muß das Session-Konzept einmal verstehen, und dazu sind die beiden Links die Du jetzt erhalten hast hervorragend geeignet. Lies Dir das mal durch und wenn Du dann noch Fragen hast frag ;-)

            Grüße
            Andreas

            1. Hallo Andreas,

              nochmals vielen Dank für deinen neuen Ansatz, obwohl dieser ja ähnlich dem ersten ist. Ich denke, dass ich das Prinzip
              einigermaßen verstanden habe. Werde mich dann wohl mal darin versuchen. Wollte mir eh noch einige Dinge in PHP aneignen,
              denn da bin ich doch eher noch Anfänger (also werde ich sicher noch öfter was fragen *g*).

              Vielen lieben Dank und viele Grüße
              Ben

              --
              Phantasie ist wichtiger als Wissen. - Albert Einstein
    2. Moin!

      Ich habe das bislang so gemacht, dass ich auf jeder Seite auf $_POST zugreife und die entsprechenden Daten wieder in hidden-inputs schreibe.

      Das ist die ungünstigste Lösung, die du dir ausgesucht hast. Diese Daten sind mit jedem Mal, wo du das Formular erneut abschickst, potenziell unsicher, da völlig ohne Probleme änderbar.

      Das macht aber doch keinen Unterschied. Wenn man mit dem Skript erstmal die Benutzereingaben auf mehreren Seiten sammelt und immer wieder in Hidden-Felder packt, ist das kein Problem. Erst das letztmalige Absenden der Daten sollte die Validierung derselben auslösen - danach darf man dann keinerlei Daten ungeprüft mehr vom Benutzer entgegennehmen.

      Ich habe das jetzt so gelöst, dass ich je nach dem, welche Möglichkeit gewählt wurde einen Header mit einer Location sende. Das Problem ist jetzt natürlich, dass dadurch die ganzen vorigen Variablen verloren gehen. :-(

      Du hast 2 Möglichkeiten.

      Nur zwei? Würde ich nicht sagen.

      Entweder du benutzt $_GET (funktioniert genau wie $_POST, nur eben für per GET übergebene Variablen und deren Werte.

      Das hat den Nachteil der Längenbeschränkung. Aber die Weiterleitung funktioniert natürlich.

      Die zweite, wesentlich sicherere Variante, mit der du auch o.g. Problem lösen kannst, heißt Sessions.

      Die ist genauso sicher oder unsicher wie jede andere Variante.

      Grob gesagt, werden die Daten, die mit einem Formular übertragen werden, auf dem Server gespeichert und sind nur anhand einer praktisch einmaligen - da mit MD5 verschlüsselten - SessionID zugreifbar.

      Die Session-ID ist nicht MD5-verschlüsselt. Es ist einfach ein 128-Bit-Wert. Das macht ihn aber nicht zwingend unsicher - entscheidend ist, einen möglichst zufälligen Wert auszuwürfeln, damit man diesen Wert nicht raten kann.

      Da liest du dich am besten mal in das Kapitel ein (http://www.php.net/manual/de/ref.session.php).

      Die beste Methode wäre, einfach den Redirect zu vermeiden.

      Irgendwo im jetzigen Skript wird festgestellt, was der Kunde wünscht. Anstatt jetzt mit header() weiterzuleiten auf eine andere Seite, kann man doch einfach den Seitencode an diese Stelle packen und wahlweise die eine oder andere Seitenvariante generieren.

      if (mail_gewünscht)
      {
        echo "Mailseite";
      }
      else
      {
        echo "Postseite";
      }

      Um es mal grob zu formulieren. Und schon stehen alle Daten wieder schön zur Verfügung.

      Ich bin grundsätzlich kein Freund von allzuvielen Redirects. Insbesondere das Absenden von Formularen darf keine Redirects benötigen. Denn der Server hat die Daten ja schon beim ersten Mal erhalten. Warum ist er zu doof, sie einfach zu bearbeiten und zu speichern? Beim Redirect muß ich alle Daten nochmal vom Browser senden lassen.

      - Sven Rautenberg

      --
      "Bei einer Geschichte gibt es immer vier Seiten: Deine Seite, ihre Seite, die Wahrheit und das, was wirklich passiert ist." (Rousseau)
      1. Hi Sven,

        Danke für deine Antwort! :)

        if (mail_gewünscht)
        {
          echo "Mailseite";
        }
        else
        {
          echo "Postseite";
        }

        Das wäre natürlich auch eine sehr einfach Variante, aber ich denke, ich werde es nun wohl zwar über Sessions lösen, aber diese Funktionsweise werde
        ich ja wahrscheinlich trotzdem noch benutzen können. :)

        Vielen Dank und viele Grüße
        Ben

        --
        Phantasie ist wichtiger als Wissen. - Albert Einstein
        1. Moin!

          if (mail_gewünscht)
          {
            echo "Mailseite";
          }
          else
          {
            echo "Postseite";
          }
          Das wäre natürlich auch eine sehr einfach Variante, aber ich denke, ich werde es nun wohl zwar über Sessions lösen, aber diese Funktionsweise werde ich ja wahrscheinlich trotzdem noch benutzen können. :)

          Warum komplizierter machen, als es sein muß? Sessions sind zwar schon recht simpel benutzbar, aber für deine Zwecke mußt du sie noch extra einbauen.

          Wenn du deine bisherigen Skripte einfach includest, könntest du dir 90% der zusätzlichen Arbeit sparen.

          - Sven Rautenberg

          --
          "Bei einer Geschichte gibt es immer vier Seiten: Deine Seite, ihre Seite, die Wahrheit und das, was wirklich passiert ist." (Rousseau)
          1. Hallo Sven,

            Wenn du deine bisherigen Skripte einfach includest, könntest du dir 90% der zusätzlichen Arbeit sparen.

            Wie genau meinst du das jetzt? Ich verstehe leider nicht ganz, was ich wie includen soll.

            Vielen Dank und viele Grüße
            Ben

            --
            Phantasie ist wichtiger als Wissen. - Albert Einstein
            1. Moin!

              Hallo Sven,

              Wenn du deine bisherigen Skripte einfach includest, könntest du dir 90% der zusätzlichen Arbeit sparen.
              Wie genau meinst du das jetzt? Ich verstehe leider nicht ganz, was ich wie includen soll.

              Es hängt natürlich von deinen Skripten ab, aber:

              Du leitest derzeit mit header('Location...') auf eine weitere Seite um. Das kannst du nur, wenn du erstens bis zum Header noch keinerlei HTML-Ausgabe gemacht hast und zweitens auch danach keinerlei HTML-Ausgabe mehr kommt.

              Mit anderen Worten: Du gibst derzeit nichts anderes aus als einen Location-Header.

              Anstelle dieses Headers kannst du also auch ohne Umleitung eine komplette HTML-Seite ausgeben. Mit anderen Worten: Statt header("Location: andere-seite.php") kannst du auch include("andere-seite.php") machen. Dann wird auf die andere Seite nicht umgeleitet, sondern sie gleich direkt ausgeführt.

              Du mußt nur zwei Punkte dabei beachten: Erstens leitet header() auf eine URL um, include bezieht sich auf das lokale Dateisystem. Und zweitens kannst du nicht mehr so sorglos in der zweiten Seite davon ausgehen, dass alle Variablen zu Beginn undefiniert sind. $_POST allerdings hat (immer noch) den von dir gewünschten und bei der Umleitung vermißten Inhalt. Erwarte also möglicherweise minimalen Trouble.

              - Sven Rautenberg

              --
              "Bei einer Geschichte gibt es immer vier Seiten: Deine Seite, ihre Seite, die Wahrheit und das, was wirklich passiert ist." (Rousseau)
              1. Hi Sven,

                Anstelle dieses Headers kannst du also auch ohne Umleitung eine komplette HTML-Seite ausgeben. Mit anderen Worten: Statt header("Location: andere-seite.php") kannst du auch include("andere-seite.php") machen. Dann wird auf die andere Seite nicht umgeleitet, sondern sie gleich direkt ausgeführt.

                Include("andereSeite) macht man aber bestenfalls mit eigenen Seiten auf ein und derselben Maschine. Wenn Übertragungswege dazwischen sind, wird es wohl ratsamer sein, darauf zu verzichten. dann solle dafür ja virtual() geben...

                Liebe Grüße aus http://www.braunschweig.de

                Tom

                --
                Intelligenz ist die Fähigkeit, aus Fehlern Anderer zu lernen und Mut die, eigene zu machen.