Ankündigung

Einklappen
Keine Ankündigung bisher.

[Erledigt] Array als Tabelle ausgeben und dabei passende Werte aus Datenbank hinzufüg

Einklappen

Neue Werbung 2019

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • [Erledigt] Array als Tabelle ausgeben und dabei passende Werte aus Datenbank hinzufüg

    Hallöchen nochmal ^^

    nachdem ich nun dank mermshaus eine biologische Kreuzung hinbekommen habe, hapert es leider noch an der Abgleichung dieser Kreuzung mit meinen Datenbankwerten :/

    In der Datenbank sind folgende Werte gespeichert:

    ID | Bezeichnung | Code
    etwa so:
    1 | gelb mit runder Frucht | AaBB
    2 | gelb mit runder Frucht | AABB

    wobei halt die IDs (und Codes theoretisch auch) unique sind, die Bezeichnungen mehrmals vorkommen können.

    Ich hätte jetzt folgendes erreicht:

    PHP-Code:
    foreach((cross($mpflanze$vpflanze)) as $fgen)
            echo 
    "<tr>" "<td>" "Hier soll die Bezeichnung des jeweiligen Codes aus der Datenbank hin" "</td>" "<td>" $fgen,"<br />" "</td>" "</tr>"
    Nun, das gibt mir auch eine schicke Tabelle aus mit allen Codes, jedoch möchte ich jetzt für jeden Code aus dem Array die Bezeichnung dazu aus der Datenbank abrufen. Hab mal schon ein bisschen geschaut, kam aber nur dazu, dass man darin keine WHILE oder gar Datenbankabfragen in dem foreach machen soll, jedoch habe ich nicht hinbekommen, es irgendwie anders zu machen..

    Abgesehen davon, dass die Bezeichnung ($row['Bezeichnung']) ausgegeben werden soll, soll, falls der Code nicht in der DB gefunden werden kann, ein "Unbekannte Kombination" ausgegeben werden. Dies hab ich so probiert, komme aber nicht weiter dass es auch klappt...

    PHP-Code:
    $strSQL="SELECT `Bezeichnung` FROM `Pflanzen` WHERE `Code` = '$fgen'";
            
    $rs mysqli_query($db_link$strSQL);
            
    $row mysqli_fetch_array($rs);
            
    $Name = ($row['Code'] ==NULL?"<span>Unbekannte Kombination</span>":$row['Bezeichnung']); 
    das $Name hatte ich versucht oben bei "Hier soll die Bezeichnung des jeweiligen Codes aus der Datenbank hin" einzusetzen, ohne Erfolg :'D ich denke mal, weil allgemein das $fgen ja erst nachher definiert wird? Zumindest wird mir so für jeden Code (auch wenn vorhanden) Unbekannte Kombination ausgegeben :/

    Hat da jemand einen Tipp (und ist verständlich, wie ich das meine)? Und sorry für Anfängerfehler ^^

    LG


  • #2
    PHP-Code:
    $statement $db->prepare('SELECT ...');
    foreach(
    $codes as $code){
        
    $statement->bindParam($code);
        
    $statement->execute();
        
    $result $statement->fetchAll();
        
    // evtl noch ein If-Konstrukt um auszuwerten was gefunden wurde
        
    echo '...';

    Perfekte Einsatzmöglichkeit für Prepared Statements. Meine Syntax ist falsch, aber so ungefähr könnte das, was du machn willst, aussehen.

    http://php.net/manual/en/mysqli.quic...statements.php
    Relax, you're doing fine.
    RTFM | php.de Wissenssammlung | Datenbankindizes | Dateien in der DB?

    Kommentar


    • #3
      Bitte keine SELECT-Statements in einer Schleife. Das ist so etwas von inneffizient. Viel lieber holst du vor der foreach eine Liste von allen Bezeichnungen die du benötigst und verarbeitest später diese.

      PHP-Code:
      $cross cross($a$b);
      $select 'SELECT bezeichnung FROM tabelle WHERE bezeichung IN(' implode(','$cross).')'
      GitHub.com - ChrisAndChris - RowMapper und QueryBuilder für MySQL-Datenbanken

      Kommentar


      • #4
        Ok, danke für die zwei Tipps

        ich werd sie mir gleich zu Gemüte führen und dran basteln, wenn Probleme auftauchen meld ich mich :'D

        LG

        Kommentar


        • #5
          Zitat von ChristianK Beitrag anzeigen
          Bitte keine SELECT-Statements in einer Schleife. Das ist so etwas von inneffizient. Viel lieber holst du vor der foreach eine Liste von allen Bezeichnungen die du benötigst und verarbeitest später diese.
          Nice, hab da mal ein bisschen rumprobiert und die Lösungsansätze verglichen

          Ausgangstabelle test

          id: int(11) primarykey
          name: varchar(75)
          35471 Einträge

          PHP-Code:
          <?php
          ini_set
          ('display_errors'1);

          $db = new PDO('mysql:host=;port=;dbname=''''');

          $ids = array(1,2,3,4,5,6,7);
          ?>
          <table>
          <?php
          $startPs 
          microtime();
          $statement $db->prepare('SELECT name FROM test WHERE id = ?');
          foreach(
          $ids as $id){
              
          $statement->execute(array($id));
              
          $resultPs $statement->fetch();
              echo 
          '<tr><td>'.$resultPs['name'].'</td></tr>';
          }
          $Zeit['PreparedStatement'] = (microtime() - $startPs) .'ms';
          ?>
          </table>

          <table>
          <?php

          // WHERE IN mit implode()
          $startImplode microtime();
          $query $db->query('SELECT name FROM test WHERE id IN('.implode(','$ids).')');
          $resultImplode $query->fetchAll();
          foreach(
          $resultImplode as $result){
              echo 
          '<tr><td>'.$result['name'].'</td></tr>';
          }
          $Zeit['Implode'] = (microtime() - $startImplode) .'ms';
          ?>
          </table>


          <table>
          <?php
          // substring() für nicht-Integer Suchbegriffe
          $str null;
          $startSubstr microtime();
          foreach (
          $ids as $id){
              
          $str.= ",'".$id."'";
          }
          $query $db->query('SELECT name FROM test WHERE id IN('.substr($str1).')');
          $resultSubstr $query->fetchAll();
          foreach(
          $resultSubstr as $result){
              echo 
          '<tr><td>'.$result['name'].'</td></tr>';
          }
          $Zeit['Substring'] = (microtime() - $startSubstr) .'ms';
          ?>
          </table>

          <pre>
          <?php
          var_dump
          ($Zeit);
          //array(3) {
          //  'PreparedStatement' =>
          //  string(10) "0.001353ms"
          //  'Implode' =>
          //  string(21) "0.00040899999999999ms"
          //  'Substring' =>
          //  string(21) "0.00039899999999998ms"
          }
          ?>
          Muss schon sagen, das Ergebnis hat mich ein bisschen überrascht. Hab ich da Fehler drin?


          EDIT:
          Gerade gemerkt, dass der Query-Cache den Vergleich implode() vs substring verfälscht.
          Ansonsten: auch bei 10.000 gesuchten IDs sind Prepared Statements langsamer als die anderen beiden Varianten.
          Relax, you're doing fine.
          RTFM | php.de Wissenssammlung | Datenbankindizes | Dateien in der DB?

          Kommentar


          • #6
            Strings im IN-Operator von SQL-Anweisungen müssen einzeln gequotet werden.
            Beispiel:
            Code:
            WHERE City IN ('Paris','London');
            Das einfache implode funktioniert nur für Integers.
            PHP-Klassen auf github

            Kommentar


            • #7
              Hm, ich hab nun die Antwort von ChristianK aufgegriffen und folgendes probiert:

              PHP-Code:
              $cross cross($mpflanze$vpflanze);
              $strSQL "SELECT `Bezeichnung` FROM `Pflanzen` WHERE `Code` IN (' . implode(',', $cross) . ')";
                      
              $rs mysqli_query($db_link$strSQL);
                      
              $row mysqli_fetch_array($rs);
                      
              $Name = ($row['Bezeichnung'] ==NULL?"<span>Unbekannt</span>":$row['Bezeichnung']);

              foreach(
              $cross as $fgen)
                      echo 
              "<tr>" "<td>" $Name "</td>" "<td>" $fgen "</td>" "</tr>"
              Allerdings gibt es mir immer Unbekannt aus, obwohl das Ergebnis in der DB vorhanden ist... Oder hab ich ein Fehler, bloß der fällt mir nicht auf?

              LG

              Kommentar


              • #8
                Dann greif noch jspits Aussage auf und korrigiere dein Statement:
                PHP-Code:
                $strSQL "SELECT `Bezeichnung` FROM `Pflanzen` WHERE `Code` IN (' . implode(',', $cross) . ')"
                oder schau es dir mal auf dem Bildschirm an...

                Das einfache implode funktioniert nur für Integers.
                Das geht auch für Strings, sofern man ausser dem Komma noch die Hochkommata davor und dahinter im glue angibt und vor und hinter dem implode-Ergebnis ein Hochkomma setzt...
                Über 90% aller Gewaltverbrechen passieren innerhalb von 24 Stunden nach dem Konsum von Brot.

                Kommentar


                • #9
                  1. Query ($strSQL) mal ausgeben lassen und schauen ob das korrekt ist, was du an die DB schickst.

                  2. mysqli_ Fehlerausgabe aktivieren http://php.net/manual/de/mysqli.error.php
                  Debugging: Finde DEINE Fehler selbst! | Gegen Probleme beim E-Mail-Versand | Sicheres Passwort-Hashing | Includes niemals ohne __DIR__
                  PHP.de Wissenssammlung | Kein Support per PN

                  Kommentar


                  • #10
                    Hm, ich habe mir mal angeschaut, wie meine Abfrage aussieht und ich denke, ich weiß wo der Fehler liegt, allerdings klappt es auch anders nicht...

                    Das was ich da gemacht habe, fragt etwa so was:

                    PHP-Code:
                    $strSQL "SELECT `Bezeichnung` FROM `Pflanzen` WHERE `Code` IN ('AaBb,Aabb,aaBb,aabb')"
                    so wie ich verstanden habe, müsste es aber so sein:

                    PHP-Code:
                    $strSQL "SELECT `Bezeichnung` FROM `Pflanzen` WHERE `Code` IN ('AaBb','Aabb','aaBb','aabb')"
                    Edit: Problem mit Groß- und Kleinschreibung gelöst, hatte verpeilt, die Kollation vernünftig zu wählen -.-

                    Nochmal Edit: ja, das mit den Hochkommas hab ich nun gelöst, allerdings ist das Ergebnis noch immer falsch :/ Hier jetzt der Code und was da falsch läuft..

                    PHP-Code:
                    $cross cross($mpflanze$vpflanze);
                    $test '\''.str_replace(",","','",implode(','$cross)).'\'';

                    $strSQL "SELECT `Bezeichnung` FROM `Pflanzen` WHERE `Code` IN ($test)";
                            
                    $rs mysqli_query($db_link$strSQL);
                            
                    $row mysqli_fetch_array($rs);
                            
                    $Name = ($row['Code'] ==NULL?"<span>Unbekannt</span>":$row['Bezeichnung']);

                    foreach(
                    $cross as $fgen)
                            echo 
                    "<tr>" "<td>" $Name "</td>" "<td>" $fgen "</td>" "</tr>"
                    die Abfrage:
                    PHP-Code:
                    SELECT `BezeichnungFROM `PflanzenWHERE `CodeIN ('AaBb','Aabb','aaBb','aabb'
                    im phpMyAdmin gibt mir folgendes aus:

                    Bezeichnung
                    ------------
                    rot-runzelig
                    rot-glatt
                    gelb-runzelig
                    gelb-glatt

                    jedoch gibt mir meine Tabelle von oben (in dem foreach) nur aus:

                    rot-runzelig | AaBb
                    rot-runzelig | Aabb
                    rot-runzelig | aaBb
                    rot-runzelig | aabb

                    die Abfrage an sich ist also richtig jetzt, aber die Ausgabe in der Tabelle ist noch falsch - wie kann ich das beheben?


                    LG

                    Kommentar


                    • #11
                      Wo ist die Schleife, die die Einträge aus der DB abruft?
                      Zitat von nikosch
                      Macht doch alle was Ihr wollt mit Eurem Billigscheiß. Von mir aus sollen alle Eure Server abrauchen.

                      Kommentar


                      • #12
                        Ja, tkausl, das habe ich mir auch gedacht, dass das fehlt, allerdings weiß ich ehrlich gesagt nicht, wo ich die Schleife starten und aufhören muss. Hatte schon zwei Varianten ausprobiert, lieferte mir allerdings nicht das Ergebnis :/ kannst Du mir einen Tipp geben?

                        LG

                        Kommentar


                        • #13
                          Einen Tipp? Alles was pro Zeile in der Datenbank einmal ausgeführt werden muss gehört mit in die Schleife.

                          Deine foreach ist total unnötig. Du brauchst nicht die Ursprungsdaten sondern die Zeilen aus der Datenbank.
                          Dein echo willst du pro Zeile haben, also mit in die neue Schleife.
                          Dein $Name wird auch nur einmalig gesetzt, kein Wunder dass du 4 mal genau den gleichen Namen bekommst. Das muss dementsprechend auch mit in die Schleife.
                          Zitat von nikosch
                          Macht doch alle was Ihr wollt mit Eurem Billigscheiß. Von mir aus sollen alle Eure Server abrauchen.

                          Kommentar


                          • #14
                            Zitat von tkausl Beitrag anzeigen
                            Deine foreach ist total unnötig.
                            Ok, ja wenn ich es weglasse, funktioniert es auch alles prima mit der Ausgabe, wenn ich es so schreibe:

                            PHP-Code:
                            $cross cross($mpflanze$vpflanze);
                            $test '\''.str_replace(",","','",implode(','$cross)).'\'';

                            $strSQL "SELECT `Bezeichnung` FROM `Pflanzen` WHERE `Code` IN ($test)";
                                    
                            $rs mysqli_query($db_link$strSQL);
                                WHILE (
                            $row mysqli_fetch_array($rs)) {
                                       
                            $Name = ($row['Code'] ==NULL?"<span>Unbekannt</span>":$row['Bezeichnung']);

                                    echo 
                            "<tr>" "<td>" $Name "</td>" "<td>" $row['Bezeichnung'] . "</td>" "</tr>";} 
                            Ich kann es jetzt nicht testen, aber jetzt macht die Sache mit dem "Unbekannt" keinen Sinn mehr, oder? Denn jetzt wird zwar ein Unbekannt ausgegeben, aber nicht daneben der "errechnete" Buchstabencode, der nicht in der DB vorhanden ist, sondern eine nicht vorhandene Bezeichnung, also nichts. Ist ja nicht so ganz der Sinn der Sache :/

                            LG & Danke für den Tipp mit der Schleife

                            Kommentar


                            • #15
                              Ah, jetzt versteh ich das mit dem unbekannt.

                              A: du speicherst dir in nem array alle "codes" die du gefunden hast und guckst dann am ende, welche dort fehlen die in $cross stehen um diese mit "unbekannt" auszugeben

                              B: du packst in der Schleife erstmal nur alles in ein Array und gehst danach erst alles durch. Am einfachsten ist es dabei, wenn du den "Code" als Key nimmst.
                              Zitat von nikosch
                              Macht doch alle was Ihr wollt mit Eurem Billigscheiß. Von mir aus sollen alle Eure Server abrauchen.

                              Kommentar

                              Lädt...
                              X