"schönes" verhindern, dass Daten bei neu laden in db geschrieben werden



  • Hallo!

    Ich arbeite grade an einer kleinen Terminverwaltung, wenn der Nutzer die Seite aktualisiert so werden die Daten öfters in die SQLite DB geschrieben.
    Dieses Problem hab' ich so gelöst:

    <?php
    
    if (!empty($sql) && sqlite_exec($sql, $db))
    {
      echo '<meta http-equiv="refresh" content="0; url=termine-admin.php">';
    }
    

    Problem: siehe hier: http://www.weiz.at/schulen/hs_1/hp_neu/terminverwaltung/termine-admin.php

    (Login-Script kommt nocht dazu und andere Sachen, hab's nur wegen des Posts hochgeladen)

    Wenn man Daten einträgt so, sieht es aus als ob der iFrame "wackelt" eben, durch das <meta..

    Wie kann ich das anders lösen?

    Achja, wie kann ich jede 2-Zeile markieren?

    Ich hab' es folgendermaßen versucht:

    $i = 0;
    while ($line = sqlite_fetch_object($result))
    {
      ++$i;
      $tmp = $i/2;
      $class = is_int($tmp) ? ' class="gray" ' : '';
      ...
    }
    

    Arbeitet aber nicht korrekt.

    Wie kann ich das sonst noch machen?

    MfG CSS


  • Mod

    durch eine header('Location: '); weiterleitung, statt dem meta refresh.
    das verhindert ein reload. natuerlich solltest du ein mehrfaches abschicken trotzdem verhindern. am besten vermutlich mit einem ticket system...



  • Der Server ist ein ISS und deshalb funzt das header("Location: "); nicht richtig.

    Was ist den ein Ticket-System?

    MfG CSS


  • Mod

    CSS schrieb:

    Der Server ist ein ISS und deshalb funzt das header("Location: "); nicht richtig.

    Nicht?
    Ich habe noch nie auf dem IIS entwickelt. Aber kannst du mir erklaeren warum? filtert der den Header irgendwie oder so? Wuerde mich aus technischer sicht mal interessieren, falls ich mal doch mit nem IIS zu tun haben sollte.

    Was ist den ein Ticket-System?

    Jedesmal wenn die Form aufgerufen wird, erstellst du eine zufaellige ID, aehnlich einer Session ID.

    diese ID, nennen wir sie ticket_id, speicherst du in eine tabelle gemeinsam mit der aktuellen session id.

    wenn die form submittet wird, wird auch diese ticket_id submittet - du testet also, ob es einen eintrag fuer diese ticket_id und session id in der ticket tabelle gibt. wenn ja, dann loescht den eintrag aus der tabelle raus - das ticket ist somit ungueltig. nun verarbeitest du die daten wie gewohnt.

    sollte aber das ticket ungueltig sein (also kein passender eintrag in der tabelle sein) dann weisst du, dass diese form schon einmal abgeschickt wurde (oder jemand ohne die form versucht zu submittet, was meistens ein 'hacking attempt' ist).

    ein nachteil dieses systems ist aber, dass der user den zurueckbutton nicht druecken darf, sonst kommt er ja zu der form mit dem bereits verwendeten ticket. deshalb darf die form nicht gecacht werden. kann aber zB bei opera, was ja sehr stark cacht, ins auge gehen, weil die form eben doch gecacht und nicht neu geladen wird.

    dafuer ist dieses system recht sicher. und gegen zufaelliges 2mal klicken oder ein reload der seite hilft es allemal.



  • @Shade of Mine

    Ich sollte wohl zuerst testen und dann posten. Ich hab' die header("Location: ");
    Methode gerade auf den Server geladen und es funzt komisch eingentlich. Im PHP 5 Kompendium, schreiben die Autoren (Hauser und Wenz), dass header("Location: ") nicht verwendet werden sollte, außer man ist sich sich,er dass das Script niemals auf einem ISS-Server laufen wird. Wegen des Bugs im ISS. Naja, steht ja auch nur ISS und nicht ISS 6.0 . Wahrscheinlich wird MS schon ein Update zur Verfügung gestellt haben. Das mit dem header() klappt jetzt auch, das Ticket-System werde ich umsetzen aber wie funktioniert denn das mit "jede zweite Zeile erkennen?"

    EDIT:
    Ticketsystem ist drin, kein wirliches:

    if ($result = sqlite_query("SELECT datum FROM termine", $db))
      {
        while ($line = sqlite_fetch_object($result))
        {
          if ($line->datum == $datum)
          {
            $ok = false;
            $error_warning= "block";
            break;
          }
        }
      }
    

    Hab' die Funktion zum Überprüfen des Formulars einfach um diesen Code erweitert.

    Ich vergleiche einfach ob das Datum schon drinnen ist, dass geht sehr komfortabel, da ich aus dem eingegebenen Datum einen Zeitstempel erzeuge...

    Vielen Dank für die Hilfe!



  • if ($result = sqlite_query("SELECT datum FROM termine", $db))
      {
        while ($line = sqlite_fetch_object($result))
        {
          if ($line->datum == $datum)
          {
            $ok = false;
            $error_warning= "block";
            break;
          }
        }
      }
    

    wtf tust du da?



  • @dql

    Ich lese alle im Formular gespeicherten Daten aus und sehe nach ob es schon existiert.

    EDIT:

    if ($result = sqlite_query("SELECT datum FROM termine WHERE datum='$datum'", $db))
    {
      $same = true;
      if ($line = sqlite_fetch_object($result))
      {
        $same = false;
        $checked['warning'] = "block";
      }
    }
    

    Uuuups!

    MfG CSS



  • danke!



  • kann aber zB bei opera, was ja sehr stark cacht, ins auge gehen, weil die form eben doch gecacht und nicht neu geladen wird.

    Konnte man nicht mit Headern dafür sorgen, das gecached wird?
    Oder halt Ticket nummer mit GET übergeben - sollte ja dann einzigartig sein...
    Oder sowas in der art...

    oder? Oo


  • Mod

    o_O schrieb:

    kann aber zB bei opera, was ja sehr stark cacht, ins auge gehen, weil die form eben doch gecacht und nicht neu geladen wird.

    Konnte man nicht mit Headern dafür sorgen, das gecached wird?

    Ja, aber es geht darum, dass der Browser nicht cachen _darf_.
    Denn er würde ja das alte Ticket cachen, was dann ja schon verbraucht wurde:

    Du hast eine Form, da trägt der User die Daten ein und die Daten werden sammt Ticket abgeschickt.
    Nun klickt der User 'Zurück' und ist wieder bei der Form und gibt jetzt andere Daten ein.

    Wenn der Browser dass gecacht hat, hat der User ein ungültiges Ticket (weil er genau das ja schon beim letzten Submit verbraucht hat).

    Und Opera cacht halt sehr viel und aggresiv, da muss man halt ein bisschen aufpassen.



  • erm...
    eigentlich meinte ich "das nichtgecached wird" ^^"



  • Kann Shade of Mine doch nicht wissen. Naja, funzt jetzt eh schon. Das Markieren jeder 2. Zeile funzt auch siehe->http://www.weiz.at/schulen/hs_1/tvss.png

    MfG CSS



  • natuerlich nich.
    deswegen hab ichs ja nochmal gesagt nachdem ich seinen und meinen post gelesen hatte ^^"

    Und das markieren jeder 2ten zeile is ja net so schwer 😉



  • Eh net, aber ich wollte es halt richtig markieren, da nach dem 3. Eintrag die Markierungen gewechselt haben.

    MfG CSS


Anmelden zum Antworten