kostenloser Webspace werbefrei: lima-city


Datenbankabfrage in While Schleife funktioniert nicht

lima-cityForumProgrammiersprachenPHP, MySQL & .htaccess

  1. Autor dieses Themas

    php-oop

    php-oop hat kostenlosen Webspace.

    Ich habe folgendes ref="/tag/problem">Problem:

    Zum Ausgeben von Datensätzen aus der DB benutze ich eine while Schleife:

    ...
    	$query = 'SELECT * FROM rezepte where kategorie_id = ' . $_GET ['kategorie'] . ' order by rezeptname';
    	$res = $abstract->query ( $query );
    
    	while ( $rezept = $abstract->fetchRow () ) {
    	
    	$rating_query = 'SELECT * FROM bewertungen where id = ' . $rezept ['id'];
    	$res = $abstract->query ( $rating_query );
    	$rating = $abstract->fetchRow ();
    	
    		echo '
    		<div id="container">
    			<div id="left">
    				<a href="' . DIR_HTML . strtolower($rezept ['kategorie_name']) . '/' . $rezept ['id'] . '-' . $name . '.php">
    				<img src="' . DIR_IMG . 'rezepte/rezeptbilder/' . $rezept ['bild'] . '" /></a>
    			</div>
    			<div id="middle">
    				<a href="' . DIR_HTML . $kategoriename . '/' . $rezept ['id'] . '-' . $name . '.php">' . $rezept ['rezeptname'] . '</a>
    			</div>
    			<div id="right">
    	  		
    	  		<div style="margin: 4px 0px 0px 3px;">' . $rating['total_votes'] . ' Bewertungen</div>
    	  		
    			</div>
    			<div class="clr"></div>
    		</div>';
    	}
    ...


    Das Problem ist diese Abfrage in der While Schleife:

    $rating_query = 'SELECT * FROM bewertungen where id = ' . $rezept ['id'];
    	$res = $abstract->query ( $rating_query );
    	$rating = $abstract->fetchRow ();


    Damit will ich erreichen, dass die Tabellenzeile aus der Tabelle "bewertungen" mit der id ausgegeben wird.
    Wenn ich das aber so mache, wird mir nur ein Datensatz ausgegeben. Lass ich die zweite Abfrage aber weg, funktioniert es wieder.

    Wie kann ich das Problem lösen?

    In der Tabelle "rezepte" sind die Datensätze gespeichert, in der Tabelle "bewertungen" die entsprechenden Bewertungen in der Spalte "id". Diese "id" entspricht der "id" aus der Tabelle "rezepte"

    Beitrag zuletzt geändert: 11.3.2012 10:05:41 von php-oop
  2. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

  3. g****e

    Wäre nett, wenn man erfahren könnte, was hinter der $abstract steckt. Wenn da zum Beispiel MySQLi hinter steckt, dann würdest du bei der Query ein Result-Object zurückkriegen, welches du nach dem ergebnis Fragen müsstest, also so:
    $query = 'SELECT * FROM rezepte where kategorie_id = ' . $_GET ['kategorie'] . ' order by rezeptname';
    	$res = $abstract->query ( $query );
    
    	while ( $rezept = $res->fetchRow () ) {

    Dafür müsste ich zumindest aber wissen, was hinter dem $abstract steckt.

    Und kleine Bemerkung nebenbei:
    $query = 'SELECT * FROM rezepte where kategorie_id = ' . $_GET ['kategorie'] . ' order by rezeptname';

    ist eine super Einfallslücke für Angreifer. Über das $_GET könnte jemand anderes eine SQL Injection tätigen, welche für dich unschön wäre.
    Mach des doch lieber so:
    $katID = intval( $_GET['kategorie'] );
    $query = 'SELECT * FROM rezepte where kategorie_id = ' . $katID . ' order by rezeptname';

    Damit bist du sicher, dass die ID, welche übergeben wird ein Integer, also eine Zahl ist.

    Liebe Grüße
  4. Autor dieses Themas

    php-oop

    php-oop hat kostenlosen Webspace.

    ggamee schrieb:
    Wäre nett, wenn man erfahren könnte, was hinter der $abstract steckt. Wenn da zum Beispiel MySQLi hinter steckt, dann würdest du bei der Query ein Result-Object zurückkriegen, welches du nach dem ergebnis Fragen müsstest, also so:
    $query = 'SELECT * FROM rezepte where kategorie_id = ' . $_GET ['kategorie'] . ' order by rezeptname';
    	$res = $abstract->query ( $query );
    
    	while ( $rezept = $res->fetchRow () ) {

    Dafür müsste ich zumindest aber wissen, was hinter dem $abstract steckt.

    Und kleine Bemerkung nebenbei:
    $query = 'SELECT * FROM rezepte where kategorie_id = ' . $_GET ['kategorie'] . ' order by rezeptname';

    ist eine super Einfallslücke für Angreifer. Über das $_GET könnte jemand anderes eine SQL Injection tätigen, welche für dich unschön wäre.
    Mach des doch lieber so:
    $katID = intval( $_GET['kategorie'] );
    $query = 'SELECT * FROM rezepte where kategorie_id = ' . $katID . ' order by rezeptname';

    Damit bist du sicher, dass die ID, welche übergeben wird ein Integer, also eine Zahl ist.

    Liebe Grüße


    Danke für den Tipp !
    Werde ich so machen!

    Hinter $abstract steckt eine Datenbankklasse
    Hier hab ich aus der Klasse mal die Funktion query kopiert:
    public function query($query) {
      	$this->result=mysql_query($query);
      	$this->counter=NULL;
      }


    und die fetchRow() funktion:

    public function fetchRow() {
      	return mysql_fetch_assoc($this->result);
      }


    Beitrag zuletzt geändert: 11.3.2012 10:44:22 von php-oop
  5. g****e

    Dann verstehe ich das
    $res = $abstract->query ( $query );

    nicht. Wenn query nichts zurückgibt, bleibt $res ja leer ;-)

    Da würde ich eher
    public function query($query) {
      	$this->result=mysql_query($query);
      	$this->counter=NULL;
                    return $this->result;
      }

    Machen, denn wenn du im MySQL-Query einen Fehler hast, würde die Funktion jetzt ein False zurückgeben. Damit könntest du das ganze dann so gestalten:
    $sql = //dein SQL code
    if ( $abstract->query( $sql ) ) {
        while //mache deinen whilekram
    } else {
        echo 'Ups, da ging was schief';
    }

    Damit könntest du prüfen, ob du im SQL Syntax einen Fehler hast. Mein SQL ist leider nicht gut, allerdings würde ich es dann nochmal lieber so probieren:

    $query = 'SELECT * FROM `rezepte` WHERE `kategorie_id` = ' . $katID . ' order by rezeptname';

    Ich glaube diese kleinen Tüddelchen (zu machen mit Umschalttaste und 2 mal die Taste links der Backspace Taste) hatten bei mir mal Fehler verursacht, weiß ich auch nicht genau warum.
    Probier erstmal aus, ob der Query richtig ist, vielleicht liegt ja hier der Käfer begraben? Wäre meine rangehensweise.

    Liebe Grüße
  6. php-oop schrieb:
    ... Wenn ich das aber so mache, wird mir nur ein Datensatz ausgegeben. Lass ich die zweite Abfrage aber weg, funktioniert es wieder.

    Wie kann ich das Problem lösen?

    In der Tabelle "rezepte" sind die Datensätze gespeichert, in der Tabelle "bewertungen" die entsprechenden Bewertungen in der Spalte "id". Diese "id" entspricht der "id" aus der Tabelle "rezepte"
    weil die datensatzfrage eigentlich noch nicht geklärt ist UND wenn ich den letzten teil richtig interpretiere, dann:
    $query = 'SELECT * FROM rezepte where kategorie_id = ' . $_GET ['kategorie'] . ' order by rezeptname';
    	$res = $abstract->query ( $query );
    
    	while ( $rezept = $abstract->fetchRow () ) {
    
    	  $rating_query = 'SELECT * FROM bewertungen where id = ' . $rezept ['id'];
    	  $res = $abstract->query ( $rating_query );
    	  while ($rating = $abstract->fetchRow ($res)) {
    
    		  echo '
    		  <div id="container">
    			  <div id="left">
    				  <a href="' . DIR_HTML . strtolower($rezept ['kategorie_name']) . '/' . $rezept ['id'] . '-' . $name . '.php">
    				  <img src="' . DIR_IMG . 'rezepte/rezeptbilder/' . $rezept ['bild'] . '" /></a>
    			  </div>
    			  <div id="middle">
    				  <a href="' . DIR_HTML . $kategoriename . '/' . $rezept ['id'] . '-' . $name . '.php">' . $rezept ['rezeptname'] . '</a>
    			  </div>
    			  <div id="right">
    
    	    		<div style="margin: 4px 0px 0px 3px;">' . $rating['total_votes'] . ' Bewertungen</div>
    
    			  </div>
    			  <div class="clr"></div>
    		  </div>';
    		}
    	}
    wobei die sicherheitskritik von @ggamee natürlich enorm wichtig ist und in meinem kode natürlich(¿) nicht engearbeitet ist! also vorsich vor nachsicht ;)

    Beitrag zuletzt geändert: 11.3.2012 11:03:03 von hemiolos
  7. Autor dieses Themas

    php-oop

    php-oop hat kostenlosen Webspace.

    hemiolos schrieb:
    php-oop schrieb:
    ... Wenn ich das aber so mache, wird mir nur ein Datensatz ausgegeben. Lass ich die zweite Abfrage aber weg, funktioniert es wieder.

    Wie kann ich das Problem lösen?

    In der Tabelle "rezepte" sind die Datensätze gespeichert, in der Tabelle "bewertungen" die entsprechenden Bewertungen in der Spalte "id". Diese "id" entspricht der "id" aus der Tabelle "rezepte"
    weil die datensatzfrage eigentlich noch nicht geklärt ist UND wenn ich den letzten teil richtig interpretiere, dann:
    $query = 'SELECT * FROM rezepte where kategorie_id = ' . $_GET ['kategorie'] . ' order by rezeptname';
    	$res = $abstract->query ( $query );
    
    	while ( $rezept = $abstract->fetchRow () ) {
    
    	  $rating_query = 'SELECT * FROM bewertungen where id = ' . $rezept ['id'];
    	  $res = $abstract->query ( $rating_query );
    	  while ($rating = $abstract->fetchRow ($res)) {
    
    		  echo '
    		  <div id="container">
    			  <div id="left">
    				  <a href="' . DIR_HTML . strtolower($rezept ['kategorie_name']) . '/' . $rezept ['id'] . '-' . $name . '.php">
    				  <img src="' . DIR_IMG . 'rezepte/rezeptbilder/' . $rezept ['bild'] . '" /></a>
    			  </div>
    			  <div id="middle">
    				  <a href="' . DIR_HTML . $kategoriename . '/' . $rezept ['id'] . '-' . $name . '.php">' . $rezept ['rezeptname'] . '</a>
    			  </div>
    			  <div id="right">
    
    	    		<div style="margin: 4px 0px 0px 3px;">' . $rating['total_votes'] . ' Bewertungen</div>
    
    			  </div>
    			  <div class="clr"></div>
    		  </div>';
    		}
    	}
    wobei die sicherheitskritik von @ggamee natürlich enorm wichtig ist und in meinem kode natürlich(¿) nicht engearbeitet ist! also vorsich vor nachsicht ;)


    Das klappt irgendwie noch nicht. Es wird nur ein Datensatz ausgegeben und nicht alle, die in der Tabelle "rezepte" unter der kategorie id gespeichert ist.

    Ich habe es jetzt so:

    $rezept_query = 'SELECT * FROM dl_rezepte where kategorie_id = ' . $katID . ' order by rezeptname';
    	$res = $abstract->query ( $rezept_query );
    	
    	while ( $rezept = $abstract->fetchRow () ) {
    			
    	$rating_query = 'SELECT * FROM dl_rezept_bewertungen where id = ' . $rezept ['id'];
    	  $res = $abstract->query ( $rating_query );
    	  while ($rating = $abstract->fetchRow () ) {
    	
    		echo '
    
    ...
    
    ' . $rating['total_votes'] . ' Bewertung
    
    ...
    
    ';		
    	
    	}
    	}


    Beitrag zuletzt geändert: 11.3.2012 11:21:34 von php-oop
  8. g****e

    Oh man, ich muss dringend aussschlafen....-.-

    Ja, ok, du hast da einen kleinen Logikfehler. Tut mir leid, das habe ich total übersehen.
    In der Whileschleife selbst machst du ja nocheine Query, und überschreibst damit das result der ersten Query. Also:

    Query
    while (Query)
    newQuery
    while newQuery

    Und die Resouce der alten Query hast du überschrieben. Abhilfe schafft sich, indem du die Resoucen auswärts lagerst:
    public function query($query) {
      	$this->result=mysql_query($query);
      	$this->counter=NULL;
                    return $this->result;
      }
    
    public function fetchRow( $result = NULL ) {
    if ( $result === NULL ) {
      	return mysql_fetch_assoc($this->result);
    } else {
      	return mysql_fetch_assoc($result);
    }
      }


    $rezept_query = 'SELECT * FROM dl_rezepte where kategorie_id = ' . $katID . ' order by rezeptname';
    	$rezepte_res = $abstract->query ( $rezept_query );
    	
    	while ( $rezept = $abstract->fetchRow ( $rezepte_res ) ) {
    			
    	$rating_query = 'SELECT * FROM dl_rezept_bewertungen where id = ' . $rezept ['id'];
    	  $rating_res = $abstract->query ( $rating_query );
    	  while ($rating = $abstract->fetchRow ( $rating_res ) ) {


    So besser?
    Tut mir leid, ich bin noch Müde :-D

    Liebe Grüße
  9. Autor dieses Themas

    php-oop

    php-oop hat kostenlosen Webspace.

    ggamee schrieb:
    Oh man, ich muss dringend aussschlafen....-.-

    Ja, ok, du hast da einen kleinen Logikfehler. Tut mir leid, das habe ich total übersehen.
    In der Whileschleife selbst machst du ja nocheine Query, und überschreibst damit das result der ersten Query. Also:

    Query
    while (Query)
    newQuery
    while newQuery

    Und die Resouce der alten Query hast du überschrieben. Abhilfe schafft sich, indem du die Resoucen auswärts lagerst:
    public function query($query) {
      	$this->result=mysql_query($query);
      	$this->counter=NULL;
                    return $this->result;
      }
    
    public function fetchRow( $result = NULL ) {
    if ( $result === NULL ) {
      	return mysql_fetch_assoc($this->result);
    } else {
      	return mysql_fetch_assoc($result);
    }
      }


    $rezept_query = 'SELECT * FROM dl_rezepte where kategorie_id = ' . $katID . ' order by rezeptname';
    	$rezepte_res = $abstract->query ( $rezept_query );
    	
    	while ( $rezept = $abstract->fetchRow ( $rezepte_res ) ) {
    			
    	$rating_query = 'SELECT * FROM dl_rezept_bewertungen where id = ' . $rezept ['id'];
    	  $rating_res = $abstract->query ( $rating_query );
    	  while ($rating = $abstract->fetchRow ( $rating_res ) ) {


    So besser?
    Tut mir leid, ich bin noch Müde :-D

    Liebe Grüße


    Danke, so funktioniert es!
    Auch danke an die anderen ;)
  10. oh! das mit dem zweiten $res habe eigentlich ich verbockt :( tut leid! ich bin auch noch müde.
  11. Schlechte Lösung. Niemals! Abfragen in Schleifen machen. Damit spammst du die DB mit Anfragen zu.

    Sinnvoller wäre hier die IDs zu sammeln und anschließend eine! Abfrage zu machen.

    $rating_query = 'SELECT * FROM dl_rezept_bewertungen where id IN ($ids);

    $ids sind die gesammelten IDs der vorherigen Abfrage mit Komma getrennt. Bsp: 1, 4, 75, 252,12
    Das Ergebnis der Abfrage musst du dann nur noch anhand der ID den vorherigen Datensätzen zuordnen.
  12. Diskutiere mit und stelle Fragen: Jetzt kostenlos anmelden!

    lima-city: Gratis werbefreier Webspace für deine eigene Homepage

Dir gefällt dieses Thema?

Über lima-city

Login zum Webhosting ohne Werbung!