Engin: Code schnipsel kombinieren, Kommentar Script - Reload sperre

Hi,

versuch seid Gestern schon zwei Scripte zu kombinieren, nur fehlt mir da wohl noch
der richtige kombinationssinn.

Also, ich hab ein Kommentar-Script, ansich auch ein recht gutes, nur hat das Script keine
Reload sperre, auf der suche nach einer Reload sperre habe ich Björn Schottes - Formular Reloads verhindern Artikel gefunden.

Ich habe Gestern Stunden damit verbracht, das Script von Björn in das Kommentar Script
einzubinden, nur will das irgendwie nicht. Es lässt sich zwar einbinden,
nur verhindert es dann keine reloads mehr.

Hier mal die Scripte, das erste nur auf form beschränkt,
wenn der gesamte Code nötig sein sollte ist hier noch das gesamte Script als Text Datei.

  
<form name="Form" action="<?php echo $_SERVER["PHP_SELF"] ?>" method="POST">  
  
   <input type="text" name="Kommentator" size="28" value="Name" title="Name">  
   <textarea rows="4" cols="21" name="Kommentar">Kommentar</textarea><br>  
  
<?php  
 // Dateiname ermitteln  
 $titel=explode("/","$_SERVER[PHP_SELF]");  
 $file=explode('.',ucfirst($titel[count($titel)-1]));  
 echo "   <input type='hidden' name='Kdateiname' value='".$file[0]."'>\r";  
?>  
    <input type="reset" value="löschen"> &nbsp;  
    <input type="submit" value="Absenden" name="absenden1">  
  
</form>

Und Björns Script, das den Reload verhindern soll

  
<?php  
$token = md5(uniqid('foobarmagic'));  
?>  
  
<?php  
class formreload {  
    /**  
     * In welchem Array werden die Tokens in der Session gespeichert?  
     * @var        string  
     * @access    private  
     */  
    var $tokenarray = '__token';  
    /**  
     * Wie soll das hidden element heißen?  
     * @var        string  
     * @access    public  
     */  
    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;  
        }  
    }  
}  
?>  
  
Das dazu gehörige Programm sähe so aus:  
  
<?php  
session_start();  
include_once 'dateimitderklasse.php';  
$f =& new formreload;  
  
if (isset($_POST['submit'])) {  
    /**  
     * Formular wurde submitted  
     */  
    if ($f->easycheck()) {  
        print "Ok, Daten können gespeichert werden.";  
    } else {  
        print "Sie haben einen Reload gemacht";  
    }  
} else {  
    /**  
     * Formular anzeigen  
     */  
    printf("<form action='%s' method='post'>%s",$PHP_SELF,$f->get_formtoken());  
    print "<input type='text' name='name'>";  
    print "<input type='submit' name='submit' value='Klick mich!'>";  
    print "</form>";  
}  
?>

Wie kann ich diese beiden kombinieren, ich habe schon mit den input hidden und form Elementen
alles mögliche probiert, nur funktioniert irgendwie nichts davon.

Grüße,
Engin
 GYRO

  1. Ohne das ich mir jetz den ganzen Code durchgelesen habe und den auch zu verstehen veruscht habe. Habe ich eine Frage. Warum verwendest du so eine komplexe reloadsperre für Formulare?

    1. Baue in ein Formular ein Hidden-Feld ein das einen vorher generierten Zufallsstring enthält. Du speicherst diesen String zusammen mit der Ip des Users. (vorsicht bei Proxy's)

    2. Wenn du die Anfrage dann bekommst vergleichst du den String im Feld mit dem den du auf dem Server gespeichert hast. Stimmt der Wert überein wir das Formular verarbeitet wenn nicht entsprechend darauf reagieren ;)

    3. Beim erneuten ausliefern des Formulars wird der String verändert und wieder gespeichert.

    So ist ein Reload unmöglich. Man muss die Daten neu eingeben.
    Eine einfache aber sehr effektive Möglichkeit.

    1. Hi omi,

      1. Baue in ein Formular ein Hidden-Feld ein das einen vorher generierten Zufallsstring enthält. Du speicherst diesen String zusammen mit der Ip des Users. (vorsicht bei Proxy's)

      Das problem ist, das das Formular ja schon existiert, ich kann sowas nicht bauen, habe aber deine Tipps berücksichtigt
      und ein wenig gegooglet.

      function random_string($length,$characters='abcdefghijklmnopqrstuvwxyz0123456789')  
       {  
        $random_string = '';  
        $characters_length = strlen($characters);  
        for($i=0;$i<$length;$i++)  
         {  
          $random_string .= $characters[mt_rand(0, $characters_length - 1)];  
         }  
        return $random_string;  
       }  
        
      # ausgabe  
        
      $zufallsstring = random_string(10);  
      
      

      das würde mir einen Zufallstring erzeugen und mit

      $ipadresse ="$REMOTE_ADDR";

      Hätte ich die IP, wie kann ich diese beiden Variablen zusammen für ein Hidden Feld benutzen?

      1. Wenn du die Anfrage dann bekommst vergleichst du den String im Feld mit dem den du auf dem Server gespeichert hast. Stimmt der Wert überein wir das Formular verarbeitet wenn nicht entsprechend darauf reagieren ;)

      Da muss dann wohl ne if/else anweisung werkeln, das würde ich wahrscheinlich auch
      hinkriegen, wenn ich das erste fertig habe.

      1. Beim erneuten ausliefern des Formulars wird der String verändert und wieder gespeichert.

      Das wäre dann default oder? Also da müsste ich nichts mehr machen.

      Grüße,
      Engin
       GYRO

      1. Hi,

        function random_string(...)
        das würde mir einen Zufallstring erzeugen

        Das wuerde uniqid() auch, und sogar "besser".

        und mit
        $ipadresse ="$REMOTE_ADDR";
        Hätte ich die IP

        Nutze bitte $_SERVER['REMOTE_ADDR'], Stichwort register_globals=off.
        Und die Umkopiererei in eine andere Variable kannst du dir auch sparen - der Wert steht dir die ganze Scriptlaufzeit ueber in $_SERVER['REMOTE_ADDR'] zur Verfuegung, und dort steht er gut.

        Hätte ich die IP, wie kann ich diese beiden Variablen zusammen für ein Hidden Feld benutzen?

        Die IP brauchst du gar nicht per hidden field uebergeben, denn die bekommst du beim naechsten Request ja auch wieder auf dem gleichen Wege mitgeliefert.

        MfG ChrisB

        1. Hi ChrisB,

          bevor ich mich wieder Hals über Kopf in die suche stürze kurz paar fragen

          Das wuerde uniqid() auch, und sogar "besser".

          danach werde ich mich mal umsehen, nur wenn es mit meiner genannten auch geht,
          kann diese auch bleiben, hauptsache es funktioniert erstmal.

          Nutze bitte $_SERVER['REMOTE_ADDR'], Stichwort  register_globals=off.
          Und die Umkopiererei in eine andere Variable kannst du dir auch sparen - der Wert steht dir die ganze Scriptlaufzeit ueber in $_SERVER['REMOTE_ADDR'] zur Verfuegung, und dort steht er gut.

          Also, meine Logik sagt mir jetzt:

          Ich muss einem hidden Feld einen zufallsstring übergeben, in einer
          if/else bedingung prüfe ich dann, ob der zufallsstring + die ermittelte
          IP schon was ge_POSTET haben,

          wenn ja, dann z.b. mit Header Location auf eine Seite umleiten,

          wenn nicht, Script ausführen

          Liege ich da richtig?
          Die IP dann wahrscheinlich beim betreten der Seite Speichern!?!

          Grüße,
          Engin
           GYRO

          1. Hi,

            Also, meine Logik sagt mir jetzt:

            Ich muss einem hidden Feld einen zufallsstring übergeben, in einer
            if/else bedingung prüfe ich dann, ob der zufallsstring + die ermittelte
            IP schon was ge_POSTET haben,

            Die IP wuerde ich nicht mit einbeziehen (wollen).

            Zum einen kann das Probleme mit Nutzern geben, die ueber Proxies kommen, und zum anderen verbessert es das ganze eigentlich nicht.

            Das wuerde uniqid() auch, und sogar "besser".

            danach werde ich mich mal umsehen, nur wenn es mit meiner genannten auch geht,

            kann diese auch bleiben, hauptsache es funktioniert erstmal.

            Die IP mit einzubeziehen, koennte nur bei deiner selbst geschriebenen Funktion sinnvoll sein - diese sieht naemlich auf den ersten Blick nicht so aus, als ob sie so "gute" Zufallswerte liefern kann, die ein hinreichendes Masz an Eindeutigkeit mitbringen.

            Mit der hidden field Geschichte baust du eigentlich nur eine Art Session nach - Wiedererkennung eines bestimmten Clients, und Zuordnung von Information (hat diese Nachricht schon gepostet, oder nicht).

            Da waere es eigentlich sinnvoller, gleich den Session-Mechanismus von PHP zu verwenden.

            MfG ChrisB

            1. Hi ChrisB,

              Mit der hidden field Geschichte baust du eigentlich nur eine Art Session nach - Wiedererkennung eines bestimmten Clients, und Zuordnung von Information

              Also die Session geschichte kriege ich nicht auf die Kette, dafür aber die
              hidden mit uniqid()

              Also, im Script hab ich jetzt (was an sich auch funktioniert)

                
              <?  # steht an oberster stelle  
                
                 if ($_POST['user_ident'])  { sleep(2);  
                     header("Location: {$user_redirect} ");  # [1] hier ist das Problem  
                 }  
                 else if ($_POST['user_ident']) {  
                }  
                
              $user_fix = md5(uniqid(rand(), true));  # value inhalt für hidden  
              $user_redirect = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'].(!empty($_SERVER['QUERY_STRING']) ? '?'.$_SERVER['QUERY_STRING'] : '');  # User soll auf der gleichen Seite bleiben  
                
              ?>
              

              und ein hidden Feld mit <input type='hidden' name='user_ident' value='".$user_fix."'>

              [1] Ich hatte eigentlich damit gerechnet, das bei einem Redirect über die "header Location" funktion
              die Seite neu geladen wird, tut es aber nicht.

              Wenn ich auf eine andere Seite Leite, und dann beispielsweise den zurück Button benutze wird mir die Seite
              komplett neu ausgeliefert.

              Wie krieg ich denn nun den Post Cache geleert? Ich hab mir auch überlegt,
              den User erst auf eine Bestätigungs Seite zu leiten und dann wieder zurück, fänd ich persönlich aber ärgerlich,
              wenn das jemand mit mir tun würde, deshalb verzichte ich drauf.

              Ist das überhaupt so Sinvoll wie ich es bis jetzt habe?

              Grüße,
              Engin
               GYRO

              1. Hi ChrisB,

                hab grade noch ein wenig rumprobiert, ich hab da wohl ein Pfad Problem, kann
                ich aber irgendwie nicht nachvollziehen, denn wenn ich mir

                echo 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'].(!empty($_SERVER['QUERY_STRING']) ? '?'.$_SERVER['QUERY_STRING'] : '');

                wird mir die Gesamte URI ausgegeben.
                Im anfangsposting hatte ich die Variable für das redirect falsch eingebunden,
                header('Location: "$user_redirect" '); jetzt Redirected er auch,
                nur statt auf sich selbst zu leiten leitet das Script auf http://....de/kommentar/%22$user_redirect%22.

                Ich geh jetzt erstmal schlafen, werd mir das Heut Abend nochmal ansehen.

                Grüße,
                Engin
                 GYRO

                1. Hi ChrisB,

                  Ok, das hätte ich jetzt auch,

                  header("Location: $user_redirect\n ");

                  bleibt nur noch die Sache mit dem POST Cache leeren, wenn redirectet wurde.

                  Und vielleicht noch ein Paar kommentare zu dem Script an sich.

                  Grüße,
                  Engin
                   GYRO

                  1. echo $begrüßung;

                    header('Location: "$user_redirect" ');

                    Du solltest dich dringend mit den Grundlagen PHPs beschäftigen. In mit '' eingerahmten Strings werden keine Variablen erkannt und ersetzt, auch dann nicht, wenn du den Variablennamen durch die {} eindeutig kennzeichnest. Das passiert nur in mit "" eingerahmten Strings.

                    header("Location: $user_redirect\n ");

                    Was macht das \n da am Ende? Möchtest du die restlichen Header in den Body verschieben? Die Abtrennung der Header voneinander erledigt PHP bereits für dich. Wenn du nun noch zusätzlich einen Zeilenumbruch einfügst, stehen dann zwei davon im Header, was bedeutet, dass er dort zu Ende ist.

                    bleibt nur noch die Sache mit dem POST Cache leeren, wenn redirectet wurde.

                    Prüfe, ob du nicht an Umleititis leidest. Viele Anfänger betrachten den Location-Header als ihren besten Freund, wenn sie ihn erst einmal entdeckt haben. Du solltest dich stets fragen, ob es wirklich notwendig ist umzuleiten. Vielleicht hat es überhaupt keine schädlichen Auswirkungen, wenn das Formular zweimal abgesendet wurde. Man muss da nicht aus Prinzip umleiten. Per Umleitung die POST-Eingaben zu löschen versagt spätestens beim Affenformular, bzw. macht die Sache deutlich komplizierter.

                    Du erwähntest, Sessions seien dir zu schwierig. Das sieht nur so kompliziert im Handbuch aus. session_start() am Anfang des Scripts einfügen, und über $_SESSION[...] Werte ablegen und wieder lesen. Mehr ist da am Anfang gar nicht.

                    echo "$verabschiedung $name";

                    1. Hi dedlfix,

                      Du solltest dich dringend mit den Grundlagen PHPs beschäftigen. In mit '' eingerahmten Strings werden keine Variablen erkannt und ersetzt, auch dann nicht, wenn du den Variablennamen durch die {} eindeutig kennzeichnest. Das passiert nur in mit "" eingerahmten Strings.

                      Ich geh das ganze mit der freude am experimentieren an, mir fehlt die Zeit, mich da richtig einzulesen.
                      Immerhin habe ich meine erste if/else bedingung geschrieben. :)

                      header("Location: $user_redirect\n ");

                      Was macht das \n da am Ende? Möchtest du die restlichen Header in den Body verschieben?

                      Ich hab Gestern wie Wahnsinnig rumprobiert, das war die einzige möglichkeit,
                      das directen zu erzwingen, ich probiere es gleich nochmal ohne das \n.

                      Prüfe, ob du nicht an Umleititis leidest. Viele Anfänger betrachten den Location-Header als ihren besten Freund, wenn sie ihn erst einmal entdeckt haben. Du solltest dich stets fragen, ob es wirklich notwendig ist umzuleiten. Vielleicht hat es überhaupt keine schädlichen Auswirkungen, wenn das Formular zweimal abgesendet wurde.

                      Es geht hauptsächlich um die Geschichte mit dem Reload, weil das Formular dann 2 mal
                      abgeschickt wird, ich such einfach nur eine einfache möglichkeit, das zu umgehen. Ich weiss selbst,
                      das ein redirect nur ne Notlösung ist, würde mir aber für den anfang schon reichen.

                      Du erwähntest, Sessions seien dir zu schwierig. Das sieht nur so kompliziert im Handbuch aus. session_start() am Anfang des Scripts einfügen, und über $_SESSION[...] Werte ablegen und wieder lesen. Mehr ist da am Anfang gar nicht.

                      Heisst ich könnte die Variable mit dem zufallsstring auch als Session Wert
                      benutzen oder? Da muss ich mich aber nochmal richtig reinlesen,
                      ich werde aber jetzt erstmal Probieren, das nach einem Post
                      das Form Element einfach entschärft wird.

                      Grüße,
                      Engin
                       GYRO

                    2. Hi dedlfix,

                      Du erwähntest, Sessions seien dir zu schwierig. Das sieht nur so kompliziert im Handbuch aus. session_start() am Anfang des Scripts einfügen, und über $_SESSION[...] Werte ablegen und wieder lesen. Mehr ist da am Anfang gar nicht.

                      Ok, die Sache mit den Session ist wohl doch nicht so schwer, habe es hinbekommen
                      eine Session zu starten, habe es auch hingekriegt, per POST den Wert der
                      Session an eine nächste Seite zu übergeben.

                      Jetzt würde ich auch gerne ohne umleitung  arbeiten aber wie kann ich das
                      POST Cache leeren?

                      Mein bisheriger Code sieht nun so aus

                        
                      <?  
                      session_start();  
                        
                      $user_fix = md5(uniqid(rand(), true));  
                        
                      $_SESSION["user_id"] = $user_fix;  
                        
                      if ($_POST['user_id'])  {  
                      }  
                      else if ($_POST['user_id']) {  
                      }  
                        
                      ?>  
                      
                      

                      Ich hab grade probiert, das "POST" im <form> Element nach absenden in ein "GET"
                      zu ändern, klappt auch, nur verhindert das immer noch kein reload, so wie ich es haben will.

                      Grüße,
                      Engin
                       GYRO

                      1. echo $begrüßung;

                        Jetzt würde ich auch gerne ohne umleitung arbeiten aber wie kann ich das POST Cache leeren?

                        Ganz ohne Umleitung wird es leider nicht gehen. Der Trick mit der Umleitung wird verwendet, um die POST-Seite unschädlich zu machen. Du hast diese Reihenfolge:

                        GET Formular
                          POST Formular
                          GET andere verlinkte Seite, aufgerufen durch beliebige weitere Benutzeraktivität

                        Wenn der Benutzer auf dem zweiten GET ist, soll er nicht mehr mit der Zurück-Funktion auf die POST-Seite kommen, weil dadurch die Abfrage kommt, ob das Formular noch einmal gesendet werden soll, und das auch passiert, wenn der Benutzer das bejaht. Die Umleitung sorgt dafür, dass aus dem POST beim Browser ein GET wird.

                        GET Formular
                          <del>POST Formular</del><ins>GET Umleitungsziel</ins>
                          GET andere verlinkte Seite

                        Beim Zurück gelangt man nun nur noch auf GET-Seiten, die keine datenverändernden Aktion mehr auf dem Server auslösen.

                        Der Benutzer wird aber trotz Umleitung nicht gehindert, bis zum ersten GET zurückzugehen und es noch einmal abzusenden. Auch hilft das Umleiten nicht beim Affenformular, wenn der Affe Fehler gemacht hat.

                        GET Formular
                          POST Formular (mit Fehlern)
                          <del>POST Formular (alles richtig)</del><ins>GET Umleitungsziel</ins>
                          GET andere verlinkte Seite

                        Es bleibt ein POST (oder auch mehrere, je nach Intelligenz des Affen :-) stehen, das nicht durch Umleitung entschärft wurde. Diese POSTs auch in ein GET umzuleiten hat den Nachteil, dass die fehlerhaften Werte in der GET-Seite als Eingabefeldvorbelegung eingetragen werden müssen, und das zusammen mit dem Hinweis auf Fehler. Doch das will man ja meist ebenfalls vermeiden. Der Browser soll sich nur ein leeres Formular merken.

                        Die Sachlage ist also komplex und nicht einfach zu lösen. Deshalb ist so eine Umleitung nicht immer die beste und alle Probleme lösende Wahl. Und Umleititis wird es in meinen Augen dann, wenn sie dazu dient, unterschiedlichen Inhalt auszuliefern, nur weil es dem Autor einfacher erscheint, komplette Seiten zu erstellen, statt mit einer Fallunterscheidung den jeweils auszuliefernden Inhalt einzubetten.

                        Die Frage sollte also lauten: Ist es wirklich und unbedingt erforderlich, ein mehrfaches Absenden zu verhindern? Richtet es überhaupt Schaden an, oder ist es gar nur ein verschmerzbarer Schönheitsfehler? Das Gebilde mit der Umleitung ist eins, bei dem der Client mitspielen muss. Tut er es nicht, hast du ein Loch in deiner Sicherung gegen Mehrfachausführung.

                        Wenn ein mehrmaliges Abarbeiten des Formulars nicht erfolgen darf, so ist es besser, einen serverseitigen Mechanismus zu implementieren, den der Client nicht torpedieren kann. Bei "GET formular" wird ein einmaliger, ausreichend eindeutiger Zufallswert ermittelt und sowohl in einem Feld des Formulars als auch in der Session abgelegt. Beim Verarbeiten des POST-Request werden beide Werte miteinander verglichen und der in der Session gelöscht. Bei einem erneuten POST sind die Werte nicht mehr gleich, denn der in der Session ist ja nicht mehr da. Nun kann der Benutzer auch wieder bis zum GET zurückgehen und das Formular von dort aus neu zu versenden versuchen, was ihm nicht gelingen wird, weil da ja der Browser noch die Version mit dem alten Zufallswert im Cache hat. Erst ein neuer Request nach dieser Seite erzeugt einen neuen, gültigen Zufallswert, oder auch nicht, wenn das gemäß Anwendungslogik nicht sein soll.

                        Abschließend sollte mindestens das GET-Formular den Browser bitten, nicht gecachet zu werden. Bei einem Zurück wird es der Browser aus seinem/r Cache/History nehmen, denn dabei erfolgt meistens kein neuer Request. Aber bei einem normalen Link-Aufruf wird das Expires-Datum ausgewertet und die Seite neu abgerufen, was ja für die Bildung eines neuen Zufallswertes erforderlich ist.

                        echo "$verabschiedung $name";

                        1. Hi dedlfix,

                          erstmal Danke für die ausführliche Antwort.

                          Wenn der Benutzer auf dem zweiten GET ist, soll er nicht mehr mit der Zurück-Funktion auf die POST-Seite kommen, weil dadurch die Abfrage kommt, ob das Formular noch einmal gesendet werden soll, und das auch passiert, wenn der Benutzer das bejaht. Die Umleitung sorgt dafür, dass aus dem POST beim Browser ein GET wird.

                          Also derzeit habe ich eine recht kleine funktion, die an sich aber ziemlich gut arbeitet,
                          einziges Schönheitsfehler ist, das die Umleitung mit referer arbeitet,
                          werde das gleich auch noch anpassen, also statt referer die genaue URL auslesen und an die umleitung mit einer Variablen übergeben,
                          dann wäre das Script eigentlich
                          von der Funktion her völlig ausreichend.

                          Habe es auch grade mal getestet, ob nach einem Post noch der zurück Button geht,
                          geht auch nicht. Nach einem absenden merkt man nicht einmal, das man umgeleitet und wieder zurück geschickt wird.
                          Auch ohne Cookies funktioniert es, nur das dann die eintragsbestätigung nicht angezeigt wird.

                          Hatte ja im Forum Gestern einen neuen Thread aufgemacht, wo ich ein beispiel verlinkt hatte,
                          das beispiel funktioniert nicht mehr, da ich diese funktion schon in die eigentliche Seite eingebunden habe,

                          http://nispet-club.de/nispet-galerien/silvester2007-2008.php

                          Der Benutzer wird aber trotz Umleitung nicht gehindert, bis zum ersten GET zurückzugehen und es noch einmal abzusenden. Auch hilft das Umleiten nicht beim Affenformular, wenn der Affe Fehler gemacht hat.

                          Ich weiss zwar nicht genau, wie ich das gemacht hab, bei mir ist das Post Formular nach einem
                          absenden leer, ein reload unterbunden und auch die Eingaben gelöscht.
                          Der Zurück-Button bringt dich auch nur noch auf die Seite zurück, von der du gekommen bist,
                          also weder auf das Post-Formular, noch auf die redirect Datei.

                          Du kannst es ja testen, wenn du magst, die einträge kommen ja bei mir an, das heisst du kannst auch zum
                          testen "ojashodfqkwpfe qwef" schreiben und abschicken, ich lösche die Kommentare dann.

                          Die Frage sollte also lauten: Ist es wirklich und unbedingt erforderlich, ein mehrfaches Absenden zu verhindern?

                          Ich finde schon, dabei geh ich nicht einmal davon aus, das "viele" einträge gemacht werden,
                          wenn aber doch, dann sollte das Risiko mit mehrfach-Postings weitgehend unterbunden werden.

                          So wie es jetzt aussieht, ist das Script von der Funktion so einfach wie zuverlässig,
                          nur kann ich das natürlich nicht beurteilen, daher verlinke ich mal auf die
                          Scripte und Dateien, die das ganze verarbeiten.

                          http://nimmet.de/beispiele/selfhtml/htmloutput.txt Die ausgabe, in die ich das Script icludiere

                          http://nimmet.de/beispiele/selfhtml/kommentar.txt Das Formular, das alles bearbeitet

                          http://nimmet.de/beispiele/selfhtml/redirect.txt Die redirect Datei

                          http://nimmet.de/beispiele/selfhtml/schreibe.txt Das Script, das die eingaben verarbeitet

                          Vielleicht kannst du ja mal drüberfliegen und schauen, ob es so in Ordnung ist.

                          Grüße,
                          Engin
                           GYRO

                          1. echo $begrüßung;

                            Also derzeit habe ich eine recht kleine funktion, die an sich aber ziemlich gut arbeitet,
                            einziges Schönheitsfehler ist, das die Umleitung mit referer arbeitet,

                            Ja, der Nutzen des Extra-Redirect-Scripts offenbart sich mir nicht. Du hast damit zwei Redirects unmittelbar aufeinanderfolgend. Ein einzelner erfüllte auch das Ziel.

                            Habe es auch grade mal getestet, ob nach einem Post noch der zurück Button geht,
                            geht auch nicht. Nach einem absenden merkt man nicht einmal, das man umgeleitet und wieder zurück geschickt wird.

                            Du hast ja auch nur ein POST-und-Fertig-Formular, kein Affenformular oder eine Zwangsvorschau zwecks Verwirrung von Formular-Bots.

                            So wie es jetzt aussieht, ist das Script von der Funktion so einfach wie zuverlässig,
                            nur kann ich das natürlich nicht beurteilen, daher verlinke ich mal auf die
                            Scripte und Dateien, die das ganze verarbeiten.
                            Vielleicht kannst du ja mal drüberfliegen und schauen, ob es so in Ordnung ist.

                            Dein Code sieht so aus wie bei mir, als ich mit PHP anfing: unübersichtlich. Ein großes HTML-Template, das an den Stellen, an denen eine Ausgabe berechnet werden muss, unterbrochen wird. Das PHP selbst ist auch wieder mit HTML-Ausgaben versetzt. Ich habe man drübergeschaut, und mir ist nichts Kritisches aufgefallen. Das kann aber auch daran liegen, dass es sich gut in dem Wirrwar versteckt hat. Hier nur mal ein Ausschnitt, den ich kommentieren möchte.

                            ~~~php $Kommentator = $_POST["Kommentator"];
                             $Kommentar = $_POST["Kommentar"];
                             $Kdateiname = $_POST["Kdateiname"];

                              
                            Unnötiges Umkopieren. Jemand, der den Code ansehen soll, muss sich nun merken, dass in den Variablen nichts anderes als die unbehandelte Benutzeringabe steckt. Wenn du $\_POST["..."] an den Stellen nähmest, an denen du die neue Variable verwendest, sähe man sofort, was das für ein Wert ist und muss nicht erst in seinem Gedächtnis oder dem Code davor nachsehen.  
                              
                             ~~~php
                            $Kommentar = str_replace("\r", "", $Kommentar);  
                             $Kommentar = str_replace("\n", "", $Kommentar);
                            

                            str_replace() nimmt als Parameter auch Arrays an:

                            $Kommentar = str_replace(array("\r", "\n"), "", $Kommentar);

                            Jede Zeile weniger erhöht die Übersichtlichkeit. (Vorausgesetzt man erzeugt nicht aus vielen Zeilen eine Monsterzeile.)

                            $Kommentar = stripcslashes($Kommentar); // Slash ersetzen

                            Wieso die Variante mit dem c? Wenn es stripslashes() ohne c werden sollte, warum steht das dann erst hier und ohne zu prüfen, ob die Magic Quotes aktiv sind? Wenn du ein Problem mit den Magic Quotes hast, dann eleminiere sie einmalig am Scriptanfang.

                            $Kommentar = " " . $Kommentar; // Leerzeichen hinzufügen

                            Solche Kommentare sind überflüssig. Dass da ein Leerzeichen hinzukommt, sieht man unzweifelhaft am Code. Man sieht aber nicht, warum es hinzukommen soll. Wenn, dann wäre das kommentierungswürdig.

                            $Kommentar = substr($Kommentar, 0, 500); // Zeichenanzahl begrenzen

                            Das würde ich an der Stelle nicht tun. Wenn es dir zu lang ist, kannst du es immer noch bei deiner händischen Kontrolle kürzen. So verlierst du nur möglicherweise interessante Stellen aus dem Roman, den da vielleicht jemand eingetippt hat.

                            Wenn man mal vom EVA-Prinzip ausgeht, hast du bisher den V-Teil behandelt. (Und das strip(c)slashes(), das aber zum E-Teil gehört.) Nun mischst du auch noch den A-Teil in deine Variablen (die beiden rawurlencode()-Zeilen):

                            ~~~php $datum = date("d.m.y H:i",time()); // Datum
                             $Kommentar2 = $Kommentar;
                             $Kommentator2 = $Kommentator;
                             $Kommentar = rawurlencode ($Kommentar); // Umlaute und andere
                             $Kommentator = rawurlencode ($Kommentator); // Zeichen konvertieren

                              
                            und schreibst dann solch eine unübersichtliche Monsterzeile:  
                              
                             $text ="Kommentar freischalten (Link anklicken!)\r$Kommentar2\r";  
                             $text .= "Datum: $datum. - Datei: \"$Kdateiname\" - Autor: $Kommentator2\n\n $url/kommentar/schreibe.php?Kdateiname=$Kdateiname&Kommentar=$Kommentar&Kommentator=$Kommentator";  
                              
                            Das geht übersichtlicher. Alle Zeilen ab $datum kann man wie folgt ersetzen:  
                              
                              ~~~php
                            $text = [link:http://www.php.net/manual/en/function.sprintf.php@title=sprintf]([link:http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc@title=<<<MAILTEXT]  
                            Kommentar freischalten (Link anklicken!)  
                            %s  
                            Datum: %s. - Datei: "%s" - Autor: %s  
                              
                             %s/kommentar/schreibe.php?Kdateiname=%s&Kommentar=%s&Kommentator=%s  
                            [link:http://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.heredoc@title=MAILTEXT],  
                               $Kommentar,  
                               date('d.m.y H:i'),  
                               $_POST['Kdateiname'],  
                               $_POST['Kommentator'],  
                               $url,  
                               urlencode($_POST['Kdateiname']),  
                               urlencode($Kommentar),  
                               urlencode($_POST['Kommentator']));
                            

                            urlencode() ist die an der Stelle (im Query-String) richtige Funktion. rawurlencode() kommt zum Einsatz, wenn ein Wert im Path-Teil eingefügt werden soll.

                            Ausgabeformatierungen gehören in die Ausgabe. Lass in deinen Variablen die Roh-Werte stehen, also die gegebenenfalls geprüften und verarbeiteten Werte, aber ohne sie einer spezifischen Ausgabeformatierung zu unterziehen. Dann sparst du dir auch soche Teile wie $variable2 = $variable; nur um den unbehandelten Wert ebenfalls noch aufzuheben. Die Ausgabeformatierung erfolgt idealerweise erst direkt zur Ausgabe und ohne Zwischenvariablen. Außerdem ist $variable2 nicht unbedingt ein sprechender Variablenname, aus dem man den Sinn dieser Variable erkennen kann.

                            echo "$verabschiedung $name";

                            1. Hi dedlfix,

                              vielen Dank für deine ausführliche Antwort, ich gehe mal davon aus, das
                              die Test-einträge von dir sind.

                              Ich hab mir dein Post gebookmarkt, muss mich jetzt erstmal um meine Sicherheitslücken kümmern. Wenns kommt, dann kommt es dicke, muss 3 Seiten überarbeiten.

                              Nur kurz hierzu,

                              Ja, der Nutzen des Extra-Redirect-Scripts offenbart sich mir nicht. Du hast damit zwei Redirects unmittelbar aufeinanderfolgend. Ein einzelner erfüllte auch das Ziel.

                              Ich habe es anders einfach nicht hingekriegt, das nach dem Post der User auf
                              der gleichen Seite bleibt und das Post Cache geleert wird.

                              Aber wie gesagt, das muss ich jetzt erstmal ganz unten in die ToDo Liste schreiben.

                              Grüße,
                              Engin
                               GYRO