Update nur geänderte Daten und zeige geändertes an

  • PHP

Es gibt 34 Antworten in diesem Thema. Der letzte Beitrag () ist von Link.

    Update nur geänderte Daten und zeige geändertes an

    Guten Morgen,

    ich habe ein Formular mit Textfeldern (input type text), die sich automatisch mit dem Inhalt aus der MySQL Datenbank füllen. Nun gibt es einen Ändern Button (input type submit), der Änderungen, die der Nutzer an den Textfeldern vorgenommen hat, abspeichern soll.

    Nun möchte ich aber nicht jedes Feld einzeln abspeichern, sondern nur die, die auch verändert wurden. Anschließend möchte ich dem Benutzer anzeigen, dass Datensatz X, Y und Z beispielsweisse geändert und abgespeichert wurden.

    Nur wie kann ich das machen? Das Speichern der einzelnen Felder per UPDATE SET kann ich.
    Nur wie vergleiche ich zuvor die aktuellen Daten mit den veränderten Daten und speichere die ungleichen Datensätze ab und gebe diese dann aus?

    Danke im Voraus!

    PS: Geht das vll mit foreach und arrays? Wäre nett, wenn mir da jemand helfen könnte. Danke
    Hi,

    das klingt mir jetzt bissl nach Mumpitz. Wenn sich an manchen Daten gar nix geändert hat, macht es doch nix, sie auch so wieder reinzuspeichern.
    Außerdem denkst du zu kompliziert. Das müsstest du mit JavaScript machen und ist wiederum aufwändig, weil du mit hidden input Feldern arbeiten und dann serverseitig doppelt abgleichen müsstest. Mach's anders: speichere einfach alles, aber hol dir den Datensatz dann nach dem Submit als Array. Wenn du deine input-Felder so benennst wie die Spaltennamen in der Tabelle, brauchst du nur das Datensatz-Array mit dem $_POST-Array abgleichen und bei Abweichungen gibst du ne Meldung aus.

    So geht's:

    PHP-Quellcode

    1. <?php
    2. // Wenn das Formular abgesendet wurde
    3. if(isset($_POST['submit'])){
    4. $Datensatz = $db->query("SELECT * FROM `tabelle` WHERE `id` = " . $db->quote($_POST['id']))->fetch();
    5. foreach($Datensatz as $feld => $wert){
    6. if(isset($_POST[$feld])){
    7. echo $feld . " wurde im Formular &uuml;bergeben<br>";
    8. if($wert != $_POST[$feld]){
    9. echo "Der Wert von " . $feld . " wurde ge&auml;ndert<br>";
    10. }
    11. echo "<hr>";
    12. }
    13. }
    14. $res = $db->exec("UPDATE `tabelle` SET
    15. `vorname` = " . $db->quote($_POST['vorname']) . ",
    16. `nachname` = " . $db->quote($_POST['nachname']) . ",
    17. `email` = " . $db->quote($_POST['email']) . "
    18. WHERE `id` = " . $db->quote($_POST['id'])
    19. );
    20. if($res){
    21. echo "<p>Daten wurden erfolgreich gespeichert</p>";
    22. }
    23. }
    24. /**
    25. * Hier das Formular um die Daten zu ändern
    26. * Voraussetzungen:
    27. * - Du rufst z.B. http://deine-seite.de/test.php?id=12 auf für dieses Beispiel
    28. * - Du hast eine Objektinstanz von PDO der Variable $db zugewiesen
    29. */
    30. $Datensatz = $db->query("SELECT * FROM `tabelle` WHERE `id` = " . $db->quote($_GET['id']))->fetch();
    31. echo "<form method='POST'>";
    32. echo "<input type='hidden' name='id' value='" . htmlspecialchars($_GET['id']) . "'>";
    33. echo "<input type='text' name='vorname' value='" . htmlspecialchars($Datensatz['vorname']) . "' placeholder='Vorname'>";
    34. echo "<input type='text' name='nachname' value='" . htmlspecialchars($Datensatz['nachname']) . "' placeholder='Nachname'>";
    35. echo "<input type='text' name='email' value='" . htmlspecialchars($Datensatz['email']) . "' placeholder='E-Mail'>";
    36. echo "<p><input type='submit' name='submit' value='Speichern'></p>";
    37. echo "</form>";
    38. ?>


    Das Beispiel ist ungetestet, aber soweit ich sehe sollte alles korrekt sein

    Link :thumbup:
    Hello World
    Vielen Dank @Link .

    Genau so möchte ich das haben. Hast recht, wollte mir halt nur die geänderten Datensätze anzeigen lassen und da dachte ich, dass dies nur gehen würde, wenn ich vorher schon filter, was geändert wurde und nur das dann abspeichern kann.

    Muss deinen Code allerdings erst noch umschreiben, dieses PDO Zeugs kann ich erstens noch nicht (wobei das relativ verständlich ist) und zweitens ist der Treiber auf meinem Webspace nicht installiert.

    Melde mich dann, falls es Probleme geben sollte beim Umschreiben ^^

    Vielen Dank!
    Hi,

    nein da muss (und kann) vorher gar nix gefiltert werden. Stellt sich ja erst noch raus ob Daten geändert werden. Wie schon gesagt könntest du das dann mit JavaScript machen, bräuchtest aber für jedes Feld ein input hidden wo du das Original speicherst. Dann musst du serverseitig jeweils beide Felder abgleichen. Viel zuviel Aufwand. Deswegen reicht ne einmalige Überprüfung mit PHP und gut ist.

    Das PDO ist relativ einfach

    PHP-Quellcode

    1. //Irgendwo musst du mit define('VAR', 'Wert'); Konstanten definieren für user, dbname, host und passwort.
    2. $db = new PDO('mysql:host=' . MYSQL_HOST . ';dbname=' . MYSQL_NAME . ';charset=utf8', MYSQL_USER, MYSQL_PASS);
    3. $db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);


    Kannst du natürlich auf mysqli umschreiben. Macht vom Code her kaum einen Unterschied. Schade dass dein Server kein PDO kann. Eigentlich hinkt der ganz schön hinterher, PDO sollte eigentlich überall möglich sein^^ Außerdem isses einfach am geilsten :D

    Ja bei Fragen schreibst hier einfach wieder.

    Link :thumbup:
    Hello World
    So sicher bin ich mir gar nicht, ob er das wirklich nicht kann - müsste ich vielleicht echt mal ausprobieren - wobei ich dann natürlich auch sämtlichen anderen Code (z.B. der vom Formular auf der vorherigen Seite) umschreiben muss.

    Hab bisher mit PDO halt nicht viel zu tun gehabt, bei meinem nächsten Projekt kann ich das ja mal nutzen - dann nutze ich von Anfang an dieses Prinzip :D
    Hi,

    also wenn man es richtig gemacht hat, kann man ja den MySQL-Treiber im laufenden Betrieb beliebig umstellen. Deswegen rate ich ja immer jedem, sich eine Wrapper-Klasse zu schreiben. Dann kannst du zwischen mysql, mysqli und PDO wechseln wie du lustig bist. Ändern tut sich dann nur an einer einzigen Stelle die Unterscheidung, wie zu MySQL connected wird. Klingt aber so als wär das bei dir nicht der Fall ^^; Ich empfehle, mach dir ne hübsche Datenbank-Klasse. Dazu dann Methoden für Verbindung, Query und Exec-Funktionen. Sollte erstmal reichen.
    Bei Bedarf kannst du dann noch eine projektspezifische abgeleitete Klasse erstellen die Methoden für häufig auftretende Vorgänge bereitstellt. Muss aber nicht.

    Ob der PDO-Treiber bei dir läuft, kannst du ja mit nem einfach phpinfo(); herausfinden. Und dann im Browser mit STRG+F nach "pdo" suchen.

    Link :thumbup:
    Hello World
    Mit Wrappern kenn ich mich (noch) nicht aus, ist vorerst aber nicht so wichtig.

    Habe jetzt mal phpinfo(); gemacht und tatsächlich: Auf meinem Webspace befindet sich der PDO Treiber.
    Sehe aber auch gerade, dass ich nur PHP 5.3.29 installiert habe (eigentlich sollte 5.6 installiert sein).
    Ich glaube, ich sollte langsam echt mal überlegen, einen eigenen Server aufzusetzen. Vielleicht reicht für den Anfang auch ein Raspberry Pi, wobei mein Server (meine Domain) ja auch von der ganzen Welt aus erreichbar sein soll. Muss dafür ja dann auch Ports und alles freischalten. Mal sehen.
    Weil beim Hosten ist man halt nicht der "Herrscher" über den Server.
    /EDIT:
    Sehe aber auch gerade, dass man die PHP Version ändern könnte
    @Link

    Wenn die name Attribute der Input Felder nicht mit den Spaltennamen aus der DB übereinstimmen, wie baue ich dann das array auf?
    $Datensatz = array('text1' => 'Identnummer', 'text2' => 'bla', ...)?

    Oder wie gehe ich vor?

    @Linkai ich guck noch mal wo anders und überleg es mir
    Hi,

    oh, Vorsicht. Lokale Webserver in's Internet zu heben ist zwar möglich und eigentlich auch äußerst einfach. Aber davon würde ich abraten. Lass einfach.

    Bei Hostern bist du vielleicht nicht der "Herrscher" im Sinne "die Kiste steht bei mir daheim". Aber bei nem vServer hast du ja alles was du brauchst. Und bei Managed Hosting
    brauchst du dich nicht mal selbst um (Sicherheits)Updates, Ports und alles weitere kümmern. Aber theoretisch könntest du schon alles machen (SSH).

    Ein Wrapper ist im Endeffekt nur eine Klasse, die dir den Zugriff auf diverse Methoden und Eigenschaften auf einfachere Art und Weise ermöglicht. Andere Einsatzgebiete von Wrappern wär z.B. das Überschreiben von Methoden mit eigenen Methoden.

    Wenn die Namen nicht übereinstimmen, musst du es ohne Schleife machen. Also manuell.


    Link
    Hello World
    Hi,

    Ich würde das ganze mit Javascript prüfen und mit Ajax speichern

    Wär auch möglich. Aber das mit JavaScript zu prüfen wär mir viel zu blöd.
    Ob normaler Submit oder AjAX is ja auch völlig egal, weil es ja auf's gleiche rausläuft ;)

    Wenn konkurrenter Zugriff erfolgt, ist das schon von Relevanz

    @petaod Wieso dieses?


    Link :thumbup:
    Hello World

    Link schrieb:

    Wär auch möglich. Aber das mit JavaScript zu prüfen wär mir viel zu blöd.


    Wieos? Jede box erhält eine id. Beim change event wird ne function aufgerufen, welche die id als parameter will.
    darauf kann man dann die funktion aufbauen, welche prüft ob sich der value des controls geändert hat. Am ende kann man dann via ajax nur die geänderten inhalte übergeben und fertig. Nur noch das bildchen mit dem harken anzeigen lassen.
    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:

    Link schrieb:

    Wieso dieses?
    Wenn zwei Personen vom selben Datensatz unterschiedliche Records verändern, gewinnt der, der am Ende nicht nur die geänderten, sondern alle Records zurückschreibt.

    Es ist schon schwierig genug das Locking auf Recordebene zu implementieren.
    Wenn dann noch einer kommt, der den kompletten View überschreibt...
    --
    If Not Program.isWorking Then Code.Debug Else Code.DoNotTouch
    --
    @Linkai ja wie ich schon sagte, theoretisch kannst du alles Mögliche machen. Aber ich persönlich bin kein großer Freund von JavaScript. Wie der TE das umsetzt am Ende ist mir relativ. Ich hab ihm ein Beispiel gepostet, das funktioniert und das tut, was zu Beginn die Anforderung war. Er kann es so machen, oder mit JavaScript. Beides würde funktionieren, beides wäre richtig. Seine Entscheidung. Braucht man ja jetzt nicht zwei funktionierende Lösungen diskutieren...

    @petaod ah ok jetzt weiß ich was du meintest. Ja da haste recht. Dann würde ich so ein Projekt aber auch ganz anders aufziehen, von Grund auf. Ist aber ja glaub ich hier nicht der Fall. Deswegen denke ich passt das schon so.


    Also wenn man jede Anforderung eines Threaderstellers so zerpflückt und auf alle möglichen Eventualitäten einzugehen versucht, wundert es mich nicht dass hier das gespamme immer noch ein aktuelles Thema im Forum ist^^ Dem nächsten fällt sicher noch ein, dass man das mit ASP viel toller machen könnte^^ Oder dass jQuery viel besser ist als JavaScript.


    Link :thumbup:
    Hello World
    Ich diskutiere nicht :) ich wollte nur wissen, warum du von der idee so abgeneigt warst. So braucht man die seite nicht neu laden, sondern der status wird dann angezeigt.

    wenn du generell gegen javascript bist, kann ich deine reaktion nachvollziehen.

    Natürlich kann der TE auch deine variante nehmen.
    Viele Frauen kamen, viele sind gegangen, eine ist geblieben 12.5.12 <3 ich liebe dich Schatz :love: :love:
    Hm, irgendwie geht das nicht. Musste es ja umschreiben, da ich vorerst PDO nicht anwende. @Link
    Bei Änderungen steht einfach nichts.
    Ich fürchte es liegt an affected rows oder so.

    PHP-Quellcode

    1. if (isset($_POST['btnsave'])){
    2. $Datensatz = mysqli_query("SELECT * FROM `Tabelle` WHERE `Identnummer` = " . mysqli_real_escape_string($verbindung, $_POST['originalid']));
    3. foreach($Datensatz as $feld => $wert){
    4. if(isset($_POST[$feld])){
    5. echo $feld . " wurde im Formular übergeben<br>";
    6. if($wert != $_POST[$feld]){
    7. echo "Der Wert von " . $feld . " wurde geändert<br>";
    8. }
    9. echo "<hr>";
    10. }
    11. }
    12. $res = mysqli_affected_rows("UPDATE `Tabelle` SET
    13. `Identnummer` = " . mysqli_real_escape_string($verbindung, $_POST['Identnummer']) . ",
    14. ........
    15. WHERE `Identnummer` = " . mysqli_real_escape_string($verbindung, $_POST['originalid'])
    16. );
    17. if($res){
    18. echo "<p>Daten wurden erfolgreich gespeichert</p>";
    19. }
    20. };