Matthias Apsel: neuer Artikel - Reloadsperre

Om nah hoo pez nyeetz, alle!

Es gibt im Wiki einen neuen Artikel, der beschreibt, wie man das versehentlich mehrfach gesendete Formulardaten serverseitig erkennt und darauf reagieren kann. Benutzer:Apsel/Reloadsperre

Ich bitte um Anmerkungen und Hinweise.

Matthias

--
Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Ping und Pinguin.

  1. Om nah hoo pez nyeetz, alle!

    Es gibt im Wiki einen neuen Artikel, der beschreibt, wie man das versehentlich mehrfach gesendete Formulardaten serverseitig erkennt und darauf reagieren kann. Benutzer:Apsel/Reloadsperre

    Zitat:

    "Jetzt kann vor dem Speichern der Daten in die Datenbank überprüft werden,"

    Wozu diese Bockstürze?

    INSERT INTO `table` (value1, value2)  
    SELECT 'stuff for value1', 'stuff for value2' FROM `table`  
    WHERE NOT EXISTS (SELECT * FROM `table`  
          WHERE value1='stuff for value1' AND value2='stuff for value2')  
    LIMIT 1 
    

    Quelle: Stackoverflow

    Jörg Reinholz

    1. Om nah hoo pez nyeetz, Jörg Reinholz!

      Wozu diese Bockstürze?

      INSERT INTO table (value1, value2)

      SELECT 'stuff for value1', 'stuff for value2' FROM table
      WHERE NOT EXISTS (SELECT * FROM table
            WHERE value1='stuff for value1' AND value2='stuff for value2')
      LIMIT 1

        
      Weil auch doppelte Datensätze möglich sein können.  
        
      Matthias
      
      -- 
      Der Unterschied zwischen Java und JavaScript ist größer als der zwischen [Beil und Beilage](http://selfhtml.apsel-mv.de/java-javascript/index.php?buchstabe=B#beil).  
      ![](http://www.billiger-im-urlaub.de/kreis_sw.gif)  
      
      
    2. Om nah hoo pez nyeetz, Jörg Reinholz!

      Wozu diese Bockstürze?

      Bei uns hießen die Bocksterzer, Herkunft wahrscheinlich von Sterz (Vogel), die bei der Balz immer mit dem Schwanz wippen, gemeint ist das nach-hinten-Ausschlagen von Schafen und Ziegen und vielleicht auch mit allen Vieren in der Luft sein.

      INSERT INTO table (value1, value2)

      SELECT 'stuff for value1', 'stuff for value2' FROM table
      WHERE NOT EXISTS (SELECT * FROM table
            WHERE value1='stuff for value1' AND value2='stuff for value2')
      LIMIT 1

      
      > Wozu diese Bockstürze?  
        
      - Wenn die ID der einzige Primärschlüssel ist, ist die Datenbankabfrage sehr umfangreich.  
      - Im Falle eines Reloads ist die Abfrage auch überflüssig.  
      - Ich weiß auf Anhieb nicht, wie ich dem Nutzer eine aussagekräftige Fehlermeldung zukommen lassen soll, denn aus Sicht der Datenbank ist ja alles in Ordnung.  
        
      Den Nachteil, den ich an meiner Variante durchaus sehe, ist, dass man die gewünschte Funktionalität auf 3-4 Stellen im Code verteilt.  
        
      Matthias
      
      -- 
      Der Unterschied zwischen Java und JavaScript ist größer als der zwischen [Los und Losung](http://selfhtml.apsel-mv.de/java-javascript/index.php?buchstabe=L#los).  
      ![](http://www.billiger-im-urlaub.de/kreis_sw.gif)  
      
      
  2. Hallo,

    Ich bitte um Anmerkungen und Hinweise.

    "absendente Daten" ist eine interessante Wortneuschöpfung...

    Gruß
    Kalk

    1. Om nah hoo pez nyeetz, Tabellenkalk!

      "absendente Daten" ist eine interessante Wortneuschöpfung...

      in der Tat.

      Matthias

      --
      Der Unterschied zwischen Java und JavaScript ist größer als der zwischen Ork und Orkan.

  3. Tach!

    Es gibt im Wiki einen neuen Artikel, der beschreibt, wie man das versehentlich mehrfach gesendete Formulardaten serverseitig erkennt und darauf reagieren kann. Benutzer:Apsel/Reloadsperre

    Es sollte ein Hinweis eingefügt werden, dass PDO als DB-Layer verwendet wird und dass der Verbindungsaufbau im Beispiel weggelassen ist, oder dass $db ein erfolgreich initialisiertes PDO-Objekt darstellt. Das kann man sonst nur aus dem Code selbst herauslesen, wenn man PDO schon kennt. Ich plädiere für einen Kommentar in der ersten Code-Zeile, der Herkunft/Inhalt von $db kurz erklärt. Und dann sollte zumindest die Fehlerbehandlung angedeutet werden.

    $id_check ist nicht gerade ein passender Variablanname. $db->prepare() liefert ein PDOStatement, keine ID-Check-Objekt. Oft bennennt man diese Variable $stmt. Wenn es unbedingt sprechender sein muss, dann $stmt_id_check oder so. Wenn die Lebenszeit dieser Variable nur wenige beieinander stehende Codezeilen umfasst, und es keine Dopplungen gibt, dann reicht ein einfaches $stmt.

    Für Dinge, die es nur einmal in der Datenbank geben darf, nimmt man einen Unique-Index. (Der kann auch über mehrere Spalten angelegt werden.) Dann nimmt man ein einfaches Insert und prüft ob das mit einem Duplicate-Key-Fehler zurückkommt oder fehlerfrei durchläuft. Wenn man solcher Daten vorher mit Select prüft, handelt man sich ein TOCTTOU-Problem ein. Ein Select zum prüfen kann man vielleicht für eine Ajax-unterstützte Eingabe nehmen. Aber das ist mit Vorsicht zu genießen, weil das auch zur Abfrage von existierenden Benutzernamen missbraucht werden kann. - Der doppelte Benutzer ist also kein geeigneter Fall für die Reload-Sperre.

    Die Funktion array_push() lohnt sich nur, wenn mehrere Werte gleichzeitig angehängt werden sollen. Sonst ist $foo[] = 'bar'; die einfachere Variante.

    Wenn man ein Einmal-Token als Lösung nimmt, kann man eigentlich auch gleich einen CSRF-Schutz verwenden, da hat man gleich zwei Fliegen mit einer Klappe geschlagen.

    Ein besseres Anwendungsbeispiel, was nicht mit Unique-Key oder einfacher Weiterleitung oder dem möglicherweise sowieso notwendigen CSRF-Schutz erledigt ist, fällt mir grad nicht ein.

    dedlfix.

  4. hi,

    Ich bitte um Anmerkungen und Hinweise.

    Deine Daten sollen in eine DB, ok. Die könnten jedoch auch woanders hin, das Problem ist dasselbe: Beim Doppelklick sollen die Daten nur einmal ankommen. Löse das Problem vorher, nämlich da, wo die Eingaben geparst werden. Dann bist Du unabhängig von einer DB-gestützten Lösung. Gib also Deinem Formular einen unique Key.

    Sniper