MH: Erste Zeile der DB fehlt

Moin alle zusammen, ich hab mal wieder ein Problem... Und zwar hab ich auf einer meiner Seiten eine Datenbankabfrage welche alle Namen einer bestimmten Klasse abruft. Dies funktioniert auch so weit, dass ich alle bekomme jedoch nicht die aller erste Zeile der Tabelle. Leider hab ich keine Ahnung warum die 1. Zeile fehlt. Ich hab schonmal geschaut woran das liegen kann, aber alle Fehler die ich so gefunden hab woran das liegen kann, treffen bei meinem Code (meiner Meinung nach) nicht zu. Hier mein Code:


$query = sprintf(
	"SELECT *
      FROM `namen`
      WHERE `klasse` = '%s'",
	$mysqli->real_escape_string($_GET['klasse'])
);
$abf = $mysqli->query($query);


$data = sprintf(
	"SELECT `Anrede`, `Titel`, `Name`
    FROM `Lehrer`
    ORDER BY `Name` ASC"
);
$ldata = $mysqli->query($data);

while ($row1 = $ldata->fetch_array(MYSQLI_ASSOC)) {
    $lehrer[$row1['Name']] = $row1['Anrede'] . ' ' . $row1['Titel'] . ' ' . $row1['Name'];
}
?>
<table>
	<thead>
		<tr>
			<th>Vorname</th>
			<th>Nachname</th>
			<th>Lehrer</th>
			<th>hinzufügen</th>
		</tr>
	</thead>
	<tbody>
		<?php $i = 0;
			while ($row = $abf->fetch_array(MYSQLI_ASSOC)) : ?>
			<tr>
				<td><input name="vname[<?php echo $i; ?>]" id="name" value="<?php echo $row['vorname']; ?>" readonly></td>
				<td><input name="nname[<?php echo $i; ?>]" id="nname" value="<?php echo $row['nachname']; ?>" readonly></td>
				<td><input name="elehrer[<?php echo $i; ?>]" id="elehrer" value="<?php echo $row['name']; ?>"></td>
				<td>
					<select name="lehrer[<?php echo $i; ?>]" id="lehrer">
						<option value="" selected>Bitte wählen Sie einen Lehrer...</option>
						<?php	foreach ($lehrer as $name => $fullname):	?>
							<option value="<?php echo $name;	?>" ><?php echo $fullname; ?></option>
						<?php 	endforeach;	?>
					</select>
				</td>
			</tr>
		<?php $i++;
		endwhile; ?>
	</tbody>
</table>

Hat jemand eine Idee woran das liegt?
Vielen Dank schonmal
MH

akzeptierte Antworten

  1. Tach!

    Hat jemand eine Idee woran das liegt?

    Es ist unwahrscheinlich, dass irgendwo etwas verschluckt wird, was nicht auf deinen Code zurückzuführen ist. Debugging ist nun angesagt.

    Erster Schritt: Arbeiten die Querys wie erwartet? Liefern sie die gewünschte Ergebnismenge, wenn du sie direkt in beispielsweise phpMyAdmin ausführst?

    Wenn ja, dann ist der nächste Schritt, die Arbeitsweise des Programms mittels Kontrollausgaben zu analysieren. Hinter jeder Anweisung, die du notiert hast, steckt eine Absicht. Stimmt der Wunsch mit der Wirklichkeit überein?

    Zudem ist die Fehlerbeschreibung nicht verständlich genug. Was bedeutet "die erste Zeile fehlt"? Fehlt sie in der Anzeige im Browser, fehlt sie im Quellcode, also der Ausgabe von PHP? Fehlt sie bereits in der Ergebnismenge der SQL-Abfrage?

    dedlfix.

    1. Hi dedlfix, danke für deine Antwort 😀
      Manchmal denkt man einfach nicht an die einfachsten Möglichkeiten den Fehler zu finden...
      Ich hab die Abfrage im phpMyAdmin ausgeführt und herrausgefunden, dass selbst da die erste Zeile fehlt.
      Hab dann die Klasse der ersten Zeile geleert und dann nochmal die Klasse hinzugefügt und jetzt wird die 1. Zeile wieder angezeigt. Anscheinend war da noch ein Leerzeichen oder so mit drin.
      Danke nochmal
      Gruß MH

      1. Hallo MH,

        ah, hab ich also richtig geahnt 😀

        Beachte trotzdem meine Hinweise unten.

        Rolf

        --
        sumpsi - posui - clusi
  2. Hallo MH,

    ich habe mehrere Ahnungen und du hast ein paar Fehler. Hast Du eigentlich in den Browser-Entwicklertools gecheckt, ob die vermisste Zeile tatsächlich im HTML fehlt? Oder vielleicht einfach nur merkwürdig geliefert wird, so dass sie nicht zur Anzeige kommt? Prüfe das in den echten Sourcen, nicht im Elemente-Inspektor.

    Hast Du die von PHP generierte Abfrage 1:1 im phpmyadmin ausgeführt? Kommt die vermisste Zeile dann? Prüfe den Wert des klasse-Feldes der vermissten Zeile ganz genau. Stehen da Leerstellen oder andere Sonderzeichen drin, die man auf Anhieb nicht sieht, die aber die Query verhageln?

    Was Du auf jeden Fall tun solltest:

    1. Ziehe die Lehrerabfrage vor die Namenabfrage. Schließe die Lehrer-Query nach Abschluss der Schleife, in der Du sie ausliest, mit $ldata->free(). Dadurch hast Du nicht mehrere Queries parallel offen; das kostet nur unnötig SQL Server Ressourcen. Ein Fehler ist das nicht, aber andersrum ist's schöner.

    2. Gib die Namen der Spalten, die Du in der Namen-Abfrage verwendest, explizit im SQL an. SELECT * macht man im phpmyadmin, aber nicht in Programmen.

    3. Du musst die Ausgaben der Namen- und Lehrerdaten mit htmlspecialchars() maskieren. Möglicherweise stehen da Inhalte drin, die die Browseranzeige stören.

    Rolf

    --
    sumpsi - posui - clusi
    1. Hallo Rolf,
      Danke für deine Antwort. Den Fehler habe ich jetzt schon gefunden, ich werde deine Hinweise aber berücksichtigen und einbauen.

      Gruß MH

  3. Moin MH,

    zwei Fragen zu deinen SQL-Statements:

    $query = sprintf(
    	"SELECT *
          FROM `namen`
          WHERE `klasse` = '%s'",
    	$mysqli->real_escape_string($_GET['klasse'])
    );
    $abf = $mysqli->query($query);
    

    Hat es einen besonderen Grund, warum du hier auf prepare und bind verzichtest?

    $data = sprintf(
    	"SELECT `Anrede`, `Titel`, `Name`
        FROM `Lehrer`
        ORDER BY `Name` ASC"
    );
    

    Wofür brauchst du hier sprintf?

    Viele Grüße
    Robert

    1. Hi Robert,

      1. Nein es hat keine besonderen Grund warum ich auf prepare und bind verzichtet. Ich arbeite meistens mit sprintf und real_escape_string, deswegen hab ich das auch hier gemacht.
      2. Das sprintf brauche ich dort nicht (mehr). Hatte da vorher noch eine WHERE-Klausel, wozu ich das dann brachte, als ich das nicht mehr brauchte hab ich das einfach stehen lassen, weil es für die Abfrage keinen Unterschied macht.

      Gruß
      MH

      1. Hallo @MH

        die Verwendung von prepare und bind hat den Vorteil, dass

        1. du dich um das Escaping nicht mehr kümmern musst,
        2. es einen Geschwindigkeitsvorteil hat, weil das Statement „vorbereitet“ wird (Unterstützung der Datenbank vorausgesetzt).

        Viele Grüße
        Robert

        1. Tach!

          1. es einen Geschwindigkeitsvorteil hat, weil das Statement „vorbereitet“ wird (Unterstützung der Datenbank vorausgesetzt).

          Im Falle einer einzelnen SELECT-Abfrage sehe ich den Vorteil nicht. Im Gegenteil, da gehen eher zwei Roundtrips (Prepare, Execute) statt nur einem bei einfacher Query über die Leitung zum MySQL-Server. Den Vorteil gibt es nur bei mehreren Inserts mit demselben Statement.

          Zudem ist das Handling des Binding bei den nativen mysqli-Funktionen nicht besonders verwenderfreundlich ist (nur Referenz auf Variablen). Da ist PDO deutlich angenehmer zu bedienen.

          dedlfix.