PHP-Neuling: SQL Update ganze Tabelle

Moin Zusammen, da bin ich wieder 😁

Für eine kleine website mit Datenbank und Userberechtigungen habe ich mir eine kleine Userverwaltung bauen wollen.

Ich habe innerhalb meiner DB eine Tabelle namens "user". Diese enthält 6 Columns inklusive id, username, admin usw.

ich habe mir nun eine Übersichtsseite "usermanagement.php" gebastelt welche tabellarisch alle Infos auflistet. Je TD ein user, wie üblich

Das Auflisten übernimmt bei mir while

while ($userliste = $userlist->fetch_object()) {

die $userlist kommt aus einem SELECT

$userlist = $db->query("SELECT Username, wert, wert, wert, wert, wert FROM user ") or die($db->error);

Das funktioniert auch soweit. Erste Frage gleich voran:

Beim Auslesen (SELECT) der Tabelle, gibt es da Vor- und Nachteile der verwendeten Schleife? Ist ein For each besser als ein while, oder ein while besser als For ? Kann man das pauschal sagen ?

Nun aber zur eigentlichen Frage. In der angezeigten Tabelle, die aus inputs besteht, wird nun die komplette Datenbanktabelle "user" angezeigt mit 15 zeilen (da 15 user in DB).

Ich würde nun gern in dieser Übersicht direkt Bearbeiten und speichern können, weiß aber nicht wie ich den UPDATE Befehl dafür bauen muss. Ich habe ja in diesem Fall kein WHERE, dass ich sinnig nutzen kann, da ich den Befehl nicht an eine ID binden kann. Alle IDs (im Falle der Bearbeitung) sollen gespeichert werden. Ein Versuch sorgte dafür, dass jetzt alle user Administrator heissen (...)

Könnt ihr mir helfen ?

Viele Grüße, und bleibt gesund

  1. ich habe nun noch versucht, einfach für jede tr einen submit button einzubauen. das wäre auch okay.

    Also erst das while, und darunter die form

    <form action="usermanagement.php?UserID=<?=$userliste->idUser ?>" method="post">
    

    Der Button sieht dann so aus

    <input type="hidden" name="aktion" value="Speichern"><input id="" type="submit" value="Speichern" onclick="submit">
    

    Nach Submit wird dann das script gestartet, welches über GET die ID des Eintrags holt, sowie die anderen inputs per POST

    if (isset($_POST['aktion']) and $_POST['aktion']=='Speichern') {
    
    $UserID = $_GET['UserID'];
    $Username = $_POST['Username'];
    etc ...
    

    der eigentliche UPDATE Befehl funktioniert aber nicht. Die Form wird neu geladen, aber es wird nichts gespeichert

    $aktualisieren = $db->prepare("UPDATE user SET Username = ?, wert= ?, wert= ?, wert= ?, wert= ?, wert= ? WHERE idUser = $UserID");
    				$aktualisieren->bind_param('ssiiii',$Username,$wert,$wert,$wert,$wert,$wert);
    				$aktualisieren->execute() 
    				or die($db->error);	
    

    Die ersten 2 Werte sollen Strings sein, und die letzten 4 integer da hier checkboxen hin sollen (TinyINT(1) )

    Wenn ich im Script statt des $aktualisieren statements einfach ein

    echo $UserID

    rein haue, stimmt das auch. Es wird die ID ausgegeben, die ich per Speichern-Button auch gewählt habe. Also muss mein UPDATE Statement faul sein 😕

    1. Hallo PHP-Neuling,

      verstehe ich das richtig, dass Du die Anzeige so machst, dass die User in einer Tabelle angezeigt werden und jeder User in seinem eigenen Form ist? Je nachdem, wie Du das machst, führt das zu fehlerhaftem HTML. Entweder geht das Form kaputt, oder die Table. Dies hier ist nicht zulässig:

      <tr>
        <form method="post" action="...">
         <td>userid</td>
         <td>name</td>
         <td>[ ] Admin</td>
         <td>[ ] Foo</td>
         <td>[ ] Bar</td>
         <td>[ ] Baz</td>
         <td>[Speichern]</td>
        </form>
      </tr>
      

      Wenn Du Dir das im den Entwicklerwerkzeugen anguckst, dann siehst Du, dass das Form Element vor dem ersten td direkt wieder geschlossen wird und die input-Elemente in den td Elementen damit nicht Teil des Form sind. Dadurch können kommen die Inhalte der Eingabefelder in den Zellen nicht an.

      Du kannst das - wenn Du die Tabelle behalten willst - lösen, wenn Du lediglich den Submit-Button ins Form legst, das Form innerhalb des <td> anordnest in dem der Submit-Button ist, dem Form eine Id gibst (z.B. id="user_<?=$userid?>") und die Eingabefelder in der Zeile mit dem form-Attribut dem form logisch zuordnest.

      <tr>
        <form method="post" action="...">
         <td><label><span>Name </span><input type="text" name="name" required form="user_28394732"</label></td>
         <td>[ ] Admin</td>
         <td>[ ] Foo</td>
         <td>[ ] Bar</td>
         <td>[ ] Baz</td>
         <td>
            <form action="usermanagement.php?UserID=28394732" method="post" id="user_28394732" onsubmit="submit()">
              <button type="submit" name="aktion" value="speichern">Speichern</button>
             </form>
         </td>
        </form>
      </tr>
      

      Wozu Du deinen onclick-Handler am Button gebraucht hast, weiß ich nicht, ohne Klammern hätte er eh nicht funktioniert und das Submit-Event am Form ist mutmaßlich besser für den Zweck geeignet. Wenn eine Plausi schiefgeht, kannst Du dort ebenfalls mit .preventDefault() den Submit verhindern.

      Beachte das Label. Ein Input braucht ein Label, auch wenn oben irgendwo ein <th>Name</th> steht. Du kannst den span im Label visuell verstecken, so dass ihn ein Normaluser nicht sieht. Aber wer einen Screenreader nutzt, der freut sich.[1]

      Mit dem form-Attribut hängst Du allerdings den Internet Explorer ab, der kann das nicht. Für den müsstest Du im submit-Handler (den Du ja schon hast) die Feldinhalte von Hand einsammeln und per JavaScript als hidden input ans Form kleben. Ob das nötig ist, erkennst Du daran, wenn Du im Submit-Eventhandler in den Form-Elementen nach deinen zugeordneten Eingabefeldern suchst.

      Ob eine <table> das richtige semantische Element ist, darüber kann man sich vermutlich Glaubenskriege liefern. Die Alternative wäre eine <ul> mit einem <li> pro User. Innerhalb dieses <li> kannst Du ein <form> bilden und die Eingabefelder - wenn Du willst - nebeneinander anordnen (z.B. Flexbox). Du musst dann aber die Breite fix vorgeben; eine Table passt sich bei Bedarf zeilenübergreifend an die Daten an, eine Flexbox nicht. Ob man es mit Subgrid eleganter lösen kann, weiß ich nicht, diesen Teil des Grid-Standards habe ich mir noch nicht angeschaut und er ist bisher auch nur im Firefox unterstützt.

      Die User-ID sollte übrigens nicht als Klartext an den Client gehen. Ich habe oben user_28394732 geschrieben, das steht für eine Zufallszahl. In der $_SESSION speicherst Du, welche Zufallszahl zu welcher User-ID gehört, und verhinderst so, dass Dir jemand einen POST-Request scriptet, der einen ganz anderen User ändert als dieser Jemand überhaupt sehen darf. Die empfangene User-ID darfst Du dann nur verwenden, wenn in der Code-zu-Userid Tabelle der Session der Eintrag vorhanden ist (und natürlich verwendest Du dann den Eintrag aus der Tabelle, nicht den Wert aus $_GET['UserId']). Da die so erhaltene User-ID rein intern ist, kannst Du bei ihr sogar auf Kontextbehandlung verzichten. Aber Du kannst sie auch als 7. Parameter binden, statt sie ins SQL einzusetzen.


      Wenn das <form> Problem nicht ist, erklärt das aber alles nicht wo deine Daten bleiben. Dein UPDATE Statement sieht - bei aller Abstraktion - so verkehrt nicht aus. Dass deine Datenfelder nicht alle $wert heißen, sondern hier nur symbolisch sind, setze ich einfach mal voraus.

      Erster Ansatz wäre das Netzwerk-Tab in den Entwicklerwerkzeugen. Das ist einfacher, als die Werte mit echo rauszuhauen. Mach das auf und submitte einen Edit. Dann guckst Du Dir die Formulardaten in dem gesendeten POST Request an und siehst, ob die Daten kommen, die Du erwartest. Damit kannst Du das Problem auf "im Browser" oder "am Server" eingrenzen, falls Du das noch nicht zu 100% klar hast.

      Rolf

      --
      sumpsi - posui - obstruxi

      1. Für Dich selbst ist es vermutlich überflüssig, aber Du bist nicht allein auf der Welt. Ableism ist ein hartnäckiges Leiden, das man sich besser gar nicht erst einfängt ↩︎

  2. Ebenfalls moin,

    Beim Auslesen (SELECT) der Tabelle, gibt es da Vor- und Nachteile der verwendeten Schleife? Ist ein For each besser als ein while, oder ein while besser als For ? Kann man das pauschal sagen ?

    nur mal so als Faustformel: Eine for-Schleife ist gut, wenn die Anzahl der Durchläufe vorher bekannt ist; while ist gut geeignet, wenn sich die Abbruchbedingung erst in der Schleife ergibt; foreach ist das Mittel der Wahl, wenn du über Eigenschaften iterieren willst, deren Namen vorher nicht bekannt sind.

    So gesehen ist das while in deinem Fall eigentlich gut gewählt.
    Ach übrigens: Du plenkst. Soll aber mit etwas Disziplin heilbar sein.

    Ich würde nun gern in dieser Übersicht direkt Bearbeiten und speichern können, weiß aber nicht wie ich den UPDATE Befehl dafür bauen muss. Ich habe ja in diesem Fall kein WHERE, dass ich sinnig nutzen kann, da ich den Befehl nicht an eine ID binden kann. Alle IDs (im Falle der Bearbeitung) sollen gespeichert werden.

    Ich würde immer nur eine Zeile bearbeiten und zurückschreiben. Die ID der Zeile kannst du gut in einem <input type="hidden"> unterbringen.

    Ein Versuch sorgte dafür, dass jetzt alle user Administrator heissen (...)

    Wie originell! 😉

    Live long and pros healthy,
     Martin

    --
    Home is where my beer is.
    1. hi Martin,

      danke, die Faustformel hilft mir schon einmal. Das plenken war mir nun ganz neu, alte Gewohnheiten, aber gut ich gelobe Besserung... ;)

      ich hatte gerade noch meinen oberen Beitrag editiert, die ID kriege ich mithilfe der action="" übermittelt

      Wenn ich im Script statt des $aktualisieren statements einfach ein

      echo $UserID

      rein haue, stimmt das auch. Es wird die ID ausgegeben, die ich per Speichern-Button auch gewählt habe. Also muss mein UPDATE Statement faul sein 😕

      Ich hab den Fehler gefunden... 🤦 Manchmal möchte man bloß rein hauen, doch traut man sich dann nicht volles lotte ins Spiegelbild zu langen...

      Meine Variablen hießen einmal FileUpload und einmal Fileupload -> entsprechend wurden keine Werte aus den Inputs übernommen Das selbe Problem hatte ich mehrfach, weshalb sich ein total bescheuertes Fehlerbild abgezeichnet hat...

      Sorry und Danke, wie immer :)

    2. Ach übrigens: Du plenkst. Soll aber mit etwas Disziplin heilbar sein.

      Er plenkt nur hie und da, aber klempt durchgehend...