PHP while($row = $result->fetch_assoc()) 2x ausführen lassen

creamycewie

Mitglied
Hi.

ich hab folgenden Code:
PHP:
mysqli_query($article_database , $sql_command);
					if (!$result = $article_database->query($sql_command)) {
						die ('Es konnte kein SQL-Query vorbereitet werden: '.$article_database->error);
					}
					else {
				   echo ('<table id="NewProducts">
							<tr id="ImageRow">');
								while($row = $result->fetch_assoc()){
									echo ('<td class="Picture"><img id="ProductPic" width="150px" height="100%" src="'.$row['Picture1'].'" /></td>
                            				<td id="spacer"></td>');
								}
								
								echo ('</tr>
                        				<tr id="DataRow">');
								while($row = $result->fetch_assoc()){
									echo ('<td class="Text"><a href="viewproduct.php?ArticleNr='.$row['ArticleNr'].'">'.$row['ArticleNameShort'].'</a><br /><small>'.$row['Price'].' €</small></td>
                            				<td id="spacer"></td>');
								}	
								echo ('</tr>
                    </table>');
					}

Das script soll 2x den Selben while-block durchlaufen, allerdings mit anderen Daten.

Es sollte also was ähnliches wie:
HTML:
<table id="NewProducts">
						<tr id="ImageRow">
                        	<td class="Picture"><img id="ProductPic" width="150px" height="100%" src="http://ich.de/img/test.jpg" /></td>
                            <td id="spacer"></td>
                            <td class="Picture"><img id="ProductPic" width="150px" height="100%" src="http://ich.de/img/test.jpg" /></td>
                            <td id="spacer"></td>
                            <td class="Picture"><img id="ProductPic" width="150px" height="100%" src="http://ich.de/img/test.jpg" /></td>
                            <td id="spacer"></td>
                            <td class="Picture"><img id="ProductPic" width="150px" height="100%" src="http://ich.de/img/test.jpg" /></td>
                            <td id="spacer"></td>
                        </tr>
                        <tr id="DataRow">
                        	<td class="Text"><a href="">Test</a><br /><small>25,00 €</small></td>
                            <td id="spacer"></td>
                            <td class="Text"><a href="">Test</a><br /><small>25,00 €</small></td>
                            <td id="spacer"></td>
                            <td class="Text"><a href="">Test</a><br /><small>25,00 €</small></td>
                            <td id="spacer"></td>
                            <td class="Text"><a href="">Test</a><br /><small>25,00 €</small></td>
                            <td id="spacer"></td>
                        </tr>
                    </table>
im Quelltext stehen.

Er durchläuft aber den 2ten WHILE-Block nicht, im Source sehe ich nur
HTML:
<table id="NewProducts">
							<tr id="ImageRow"><td class="Picture"><img id="ProductPic" width="150px" height="100%" src="http://media.modius.at/productpictures/00001-00001/2012-03-12 17.55.11.jpg" /></td>
                            				<td id="spacer"></td><td class="Picture"><img id="ProductPic" width="150px" height="100%" src="http://ich.de/img/test.jpg" /></td>
                            				<td id="spacer"></td><td class="Picture"><img id="ProductPic" width="150px" height="100%" src="http://ich.de/img/test.jpg" /></td>
                            				<td id="spacer"></td><td class="Picture"><img id="ProductPic" width="150px" height="100%" src="http://ich.de/img/test.jpg" /></td>
                            				<td id="spacer"></td></tr>
                        				<tr id="DataRow"></tr>
                    </table>

woran kann das liegen? bzw. wie kann ich den ersten While-Block quasi "resetten"?

Danke & LG

Creamy
 
Ich stelle mir grade die frage warum du überhaupt 2 while angegeben hast, du könntest es doch in einer verarbeiten und dann die entsprechenden daten auslesen.

Wenn du nur 2 einträge haben willst, dann steuerst du das ganze mit LIMIT


ungetestet aber sollte klappen:


PHP:
$result = mysql_query($article_database , $sql_command);
if (!$result = $article_database->query($sql_command)) {
                        die ('Es konnte kein SQL-Query vorbereitet werden: '.$article_database->error);
                    }
while($row = mysql_fetch_object($result))
{ 				
echo ('<table id="NewProducts">
                            <tr id="ImageRow">');
                               echo ('<td class="Picture"><img id="ProductPic" width="150px" height="100%" src="'.$row['Picture1'].'" /></td>
                                            <td id="spacer"></td>');
                               
                                
                                echo ('</tr>
                                        <tr id="DataRow">');
                                    echo ('<td class="Text"><a href="viewproduct.php?ArticleNr='.$row['ArticleNr'].'">'.$row['ArticleNameShort'].'</a><br /><small>'.$row['Price'].' €</small></td>
                                            <td id="spacer"></td>');
                                
                                echo ('</tr>
                    </table>');
                    }
 
Zuletzt bearbeitet:
Es gibt natürlich auch noch die Möglichkeit, genau einmal while() laufen zu lassen und innerhalb der while sowohl die Daten für "ImageRow" als auch "DataRow" zu erstellen. Natürlich müsstest du dann die Ausgabe in eine Variable schreiben und erst nach der while-Schleife mit echo ausgeben. Ungefähr so:

PHP:
                    else {
                                $ImageRow = '';
                                $DataRow = '';

                                while($row = $result->fetch_assoc()){
                                   $ImageRow .= '<td class="Picture"><img id="ProductPic" width="150px" height="100%" src="'.$row['Picture1'].'" /></td>
                                            <td id="spacer"></td>';

                                    $DataRow .= '<td class="Text"><a href="viewproduct.php?ArticleNr='.$row['ArticleNr'].'">'.$row['ArticleNameShort'].'</a><br /><small>'.$row['Price'].' €</small></td>
                                            <td id="spacer"></td>';
                                }
                                
                   echo ('<table id="NewProducts">
                            <tr id="ImageRow">' . $ImageRow);

                                echo ('</tr>
                                        <tr id="DataRow">' . $DataRow);
                                echo ('</tr>
                    </table>');
                    }
 
Richtiger wäre es wie in meinem 1. Beispiel, denn dort gibt es keine "Zuweisung einer Variable innerhalb einer Bedingung"

PHP:
1. Beispiel:
// query
$row = $result->fetch_assoc();
while ($row)
{
    //bedingungen
    $row = $result->fetch_assoc();
}


Oder, wenn du es mehrfach verwenden willst:
// query
$row = $result->fetch_assoc();

$rows = array ();
while ($row)
{
    $rows[] = $row;
    $row = $result->fetch_assoc();
}

foreach ($rows as $row)
{
    // bedingungen
}
(Wieso ist hier der Erweiterte Editor abgeschaltet und verweigert somit das PHP-Tag im Editor?)
 
Zuletzt bearbeitet:
Und aus welchem Grund ist es damit richtiger (eigenartig eine Ultima-Ratio noch zu steigern)?

Weil du damit keine Variablen innerhalb einer Bedingung zuweist, ist die Bedingung nicht gegeben, ist die Variable nicht deklariert und es kommt zu Notice-Meldungen, deshalb erst mal die Bedingung sicherstellen (durch das while) und hinterher das Ergebnis davon im foreach durchlaufen, das ganze lässt sich dann natürlich auf Inhalt prüfen.

Auf die Art fange ich so was ab...hat da etwa jemand eine bessere (kürzere) Lösung?

PHP:
$count = \count ($rows);
?>
        <div id="form">
            <?php echo $html->setFormFieldsetOpen (\TITLE_MENU_MAIN); ?>
            <?php if (empty ($count)): ?>
                <p>
                    <span class="hint">
                        <?php echo \MENU_NO_MENU_AVAILABLE; ?>
                    </span>
                </p>
            <?php else: ?>
                <form action="backend.php" method="post">
    		        <table class="width-100">
                        <thead>
                            <tr>
                                <th class="width-1">
                                    <?php echo \MENU_ORDERING; ?>
                                </th>
                                
                                
                                [...]
                                
                                </th>
                            </tr>
                        </thead>
                        <tfoot>
                            <tr>
                                <td colspan="7">
                                    <?php echo $html->setHiddenFormField ('token', $token); ?>
                                    <?php echo $html->setHiddenFormField ('task', 'menu_store_ordering'); ?>
                                    <?php echo $html->setFormButton ('submit', \LABEL_ORDERING_STORE); ?>
                                </td>
                            </tr>
                        </tfoot>
                        <tbody>
                            <?php foreach ($rows as $i => $row): ?>
                                <tr class="row<?php echo ($i % 2); ?>">
                                    <td class="middle">
                                        <input type="text" name="weight[<?php echo $row['bid']; ?>]" value="<?php echo ($i + 1); ?>" size="3" maxlength="3" />
                                    </td>
                                    
                                    
                                    [...]
                                    
                                    <td>
                                        <?php echo (empty ($row['active'])) ? '<span class="italic">' . $row['title'] . '</span>' : $row['title']; ?>
                                    </td>
 
Ich verstehe immer noch nicht. Welche Variable ist nicht gesetzt? $result->fetch_assoc() liefert entweder etwas zurück oder nicht. Im Falle es liefert was zurück, wird es in $row gespeichert und die while-Bedingung ist erfüllt => der Code-Block in while wird ausgeführt. Liefert es nichts zurück, ist die while-Bedingung nicht erfüllt und der Code-Block wird nicht ausgeführt. Es hat genau den gleichen Effekt wie dein Beispiel, nur ist es kürzer und man hat damit <weniger> Code und damit <weniger> Fehlerquellen.

EDIT: Eine Notice habe ich bei dieser Art der Schleifenverarbeitung noch nie gesehen. Vielleicht zeigst du mal ein Beispiel, was das tut (auch wenn es nichts mit dem Topic zu tun hat).
 
Zuletzt bearbeitet:
sag mal Saftmeister, kann es sein das du dich irrst?

bofh1337 bezieht sich auf sein eigenes script er hat direkt im selben POST 2 varianten genannt wie man es machen könnte und hält davon das erste für die bessere Lösung, vlt redet ihr nur aneinander vorbei.
 
Ich verstehe immer noch nicht. Welche Variable ist nicht gesetzt? $result->fetch_assoc() liefert entweder etwas zurück oder nicht. Im Falle es liefert was zurück, wird es in $row gespeichert und die while-Bedingung ist erfüllt => der Code-Block in while wird ausgeführt. Liefert es nichts zurück, ist die while-Bedingung nicht erfüllt und der Code-Block wird nicht ausgeführt. Es hat genau den gleichen Effekt wie dein Beispiel, nur ist es kürzer und man hat damit <weniger> Code und damit <weniger> Fehlerquellen.

EDIT: Eine Notice habe ich bei dieser Art der Schleifenverarbeitung noch nie gesehen. Vielleicht zeigst du mal ein Beispiel, was das tut (auch wenn es nichts mit dem Topic zu tun hat).

das

PHP:
while ($row = $result->fetch_assoc())

holt ja pro Durchlauf 1 Datensatz aus der DB, wenn $row jetzt innerhalb der Bedingung weiter Verarbeitet wird:

PHP:
while ($row = $result->fetch_assoc())
{
    echo $row['title']; 
}

ist $row['title'] beim Fehlschlag der Query nicht deklariert und es kommt zu Notivce-Meldungen

wenn du zuerst die Bedingung sicherstellst:

PHP:
$rows = array ();
$row = $result->fetch_assoc();
while ($row)
{
    $rows[] = $row;
    $row = $result->fetch_assoc()
}

Ist alles, was sich im Array $rows befindet, deklariert und kann genutzt werden,- sollte die Bedingung nicht erfüllt sein, kannst du das leicht mit

PHP:
$count = count ($rows);

feststellen und eine Anweisung einbauen, die ein Hinweis auf ein leeres Ergebnis bringt, ansonsten mit foreach() abarbeiten.
Das ist zwar etwas mehr an Code und eventuell etwas Mühsamer als die gewohnte Art, aber der Code wird dadurch (meiner Meinung nach) viel sauberer :)
 
Zuletzt bearbeitet:
Zurück