katzefutter123: PHP DB-SELECt - Wo ist der Fehler?

Hallo nochmal liebes Forum. In dem folgenden Quellcode-abschnitt ist irgendwo ein Fehler. Die Seite wird nicht richtig dargestellt. Wenn ich den Abschnitt entferne klappt alles. Woran kann das liegen?

$sql = "SELECT * from tbl_pizzen";
        $query = mysqli_query($conn, $sql);
        if ($rows = mysqli_fetch_all($query)) {
            echo "<table border='1'>";
            foreach($rows as $allKey => $row)
            {
                echo "<tr>";
                foreach($row as $columnKey => $column)
                {
                    if($columnKey == 0)
                        continue;
                    echo "<td>";
                    echo $column;
                    echo "</td>";
                }
                echo "<td>";
                echo "<a href='edit.php?id=$row[0]'>edit</a>";
                echo "</td>";

                echo "<td>";
                echo "<a href='delete.php?id=$row[0]'>delete</a>";
                echo "</td>";

                echo "</tr>";
            }
            echo "</table>";
  1. Hallo nochmal liebes Forum. In dem folgenden Quellcode-abschnitt ist irgendwo ein Fehler.

    Klar.

    Die Seite wird nicht richtig dargestellt.

    Unklar. Das "nicht richtig" kann sehr viel bedeuten.

    Wenn ich den Abschnitt entferne klappt alles. Woran kann das liegen?

    Fragen:

    • Ins Error-Log gesehen?
    • In den Quelltext der resultierenden Seite gesehen? Manchmal stehen Notizen (Meldung nichtfataler Fehler) unsichtbar drin oder werden übersehen.
    • Das Resultat validiert?
    • Fehler und Notizen angezeigt? Ich würde die Variante mit define('DEBUG', 2); require_once 'use_strict.php'; empfehlen.

    Ungefragt:

    "SELECT * from tbl_pizzen" führt nur zufällig zu richtigen Ergebnissen. Setze stets die Spaltennamen ein.

    Ganz ungefragt:

    Erst Login, jetzt Pizza. Ich hoffe doch nicht, dass Du einen Webshop schreibst?

    1. Hallo

      Ungefragt:

      "SELECT * from tbl_pizzen" führt nur zufällig zu richtigen Ergebnissen. Setze stets die Spaltennamen ein.

      Als Ergänzung und ebenso ungefragt: Die Abfrage mit explizit angegebenen Spaltennamen ist nur der erste Schritt. Diesem sollte die Ausgabe mit Spaltennamen statt der Indizes. Wenn sich nämlich die Feldstruktur in der Tabelle ändert oder auch die in der Ausgabe gewünschten Felder, fängst du an, die Felder in der Ergebnismenge durchzuzählen. Solange du die Feldnamen in der Tabelle nicht veränderst, bleiben die Felder namens „id“ oder „name“ immer mit diesen Namen ansprechbar.

      $sql = "SELECT id, name from tbl_pizzen";
      /* … */
      echo "<a href='edit.php?id=$row["id"]'>edit</a>";
      

      Falls sich der Feldname in der Tabelle doch ändern sollte, kann man ihn immer noch mit dem alten Namen in der Ergebnismenge verfügbar machen und muss so nur die eine Stelle (pro Abfrage) ändern.

      $sql = "SELECT id, pizza AS name from tbl_pizzen";
      

      Tschö, Auge

      --
      Wo wir Mängel selbst aufdecken, kann sich kein Gegner einnisten.
      Wolfgang Schneidewind *prust*
  2. Hallo Katzefutter,

    ich sehe gerade, dass die geschweiften Klammern in deinem Snippet unpaarig sind. Ist das ein Kopierfehler oder ist das der Grund für dein Problem?

    Sicherlich hat Deine Tabelle nicht so viele Spalten, dass Du sie generisch in einer foreach-Schleife rausrotzen musst. Natürlich gewinnst Du damit Flexibilität (Spalte in der Datenbank dazu und Schwups ist sie in der Liste), aber eigentlich sollte man die Oberfläche nicht mit der Stahlkette ans die DB koppeln. Daher schließe ich mich mal meinen Vorrednern an und füge noch was hinzu...

    • Finger weg von SELECT *
    • Verwende MYSQLI_ASSOC als zweiten Parameter für mysqli_fetch_all, so dass deine Rows mit Feldnamen indexiert werden und nicht mit Zahlen
    • Gib die Spalten, die Du ausgeben willst, explizit aus. Das geht eigentlich mit einer Zeile pro Spalte: echo "<td>{$row['Name']}</td>";. Auf diese Weise gelingt es auch, Spalten wie "id" aus der Tabelle fernzuhalten, die da nicht reingehören.
    • Alternativ kannst Du auch die komplette Row per HereDoc raushauen. Z.B. so:
       echo <<<EOL
    <tr>
      <td>{$row['Name']}<td>
      <td>{$row['Preis']}<td>
      <td>{$row['Einkaufspreis']}<td>
      <td><a href="edit.php?id={$row['id']}">Bearbeiten</a></td>
      <td><a href="delete.php?id={$row['id']}">Löschen</a></td>
    </tr>
    EOL;
    

    Ich habe deine Methode, Aktionen per A Tag auszulösen, stehen gelassen. Dafür ist A aber eigentlich nicht gemacht. Für Aktionen auf einer Seite verwendet man eigentlich das button Tag, was aber einiges an Folgeaufwand bedeutet. Du musst die Tabelle dann in eine Form setzen und bist dann mit dem Problem konfrontiert, dass Form-Anzeige, Edit und Delete alle über die gleiche URL laufen. Oder Du nutzt das neue formaction Attribut des Buttons, aber das läuft nicht in jedem Browser. Deswegen würde ich es nicht nutzen wollen und statt dessen EIN Script verwenden, das zwischen Anzeige, EDIT-Start, EDIT-Submit, DELETE-Request und DELETE-Bestätigung unterscheidet und die nötigen HTML-Seiten für diese 5 Szenarien erzeugt. Damit das gut funktioniert, muss man ein bisschen Engineering betreiben und den Code ordentlich auf Funktionen oder Klassen verteilen - das ist alles etwas viel für den Anfang. Kannst ja mal drüber nachdenken.

    Rolf

    1. Tach!

      Ich habe deine Methode, Aktionen per A Tag auszulösen, stehen gelassen. Dafür ist A aber eigentlich nicht gemacht.

      Generell zu ergänzen habe ich, dass die Verwendung von GET-Requests ganz ungünstig für Aktionen ist, die Daten verändern. Da braucht nur mal ein Linkchecker über Delete-Links drüberzulaufen und leer ist die Datenbank (wenn das nicht noch anderweitig aufgefangen wird).

      Solange allerdings die Links nur auf Seiten führen, die die Aktion vorbereiten, also lediglich Daten lesen, dann ist dagegen nichts einzuwenden. Der eigentliche Schreibvorgang sollte dann aber ein POST-Request sein. Solche Requests werden in der Regel von Automaten nicht weiter verfolgt. Es kann durchaus sein, dass das hier der Fall ist und dann wären die A-Links[1] auch durchaus berechtigt.

      dedlfix.


      1. A-Links sind sowas wie weiße Schimmel. ↩︎

      1. Hi,

        <a name="aha">ist das so?</a>
        

        cu,
        Andreas a/k/a MudGuard

      2. Hi,

        A-Links sind sowas wie weiße Schimmel.

        naja, es gibt ja auch Blauschimmel. Lebensmittel schimmeln überhaupt in sehr unterschiedlichen Farben. Brot zum Beispiel eher grau bis grün, und Kaffeesatz sogar orange.

        So long,
         Martin

        --
        Nothing travels faster than the speed of light with the possible exception of bad news, which obeys its own special laws.
        - Douglas Adams, The Hitchhiker's Guide To The Galaxy
        1. Tach!

          A-Links sind sowas wie weiße Schimmel.

          naja, es gibt ja auch Blauschimmel.

          Und es gibt Personen, die den Namen Schimmel haben. Aber auch die sind nicht gemeint, wenn man von weißen Schimmeln spricht.

          dedlfix.