I want to fetch information from one table and loop that until it's done, with the help of a while loop. Although, I want one column to be printed only once inside the loop.
There's two solutions I've come up with...
<?php
$i = 0;
// while loop start
if($i == 0){
// stuff to print
$i++;
}
// while loop end
?>
And ofcourse, I could just make another query before the while loop.
But these methods really aren't too efficient. Is there a less messy way to do this?
Actually, I'd be okay with running another query before the while loop, if it didn't get so messy, and perhaps if I could just re-use the query intended for the loop (I fetch everything from the table). I tried experimenting with mysql_fetch_field, but I'm not sure I get how it works, or if that even helps here * embarrassed *
Currently, the code looks like so:
$fetch = mysql_query("SELECT *
FROM `pms`
JOIN `pm_conversations` ON pms.ConvID = pm_conversations.ID
WHERE `ConvID`='".$_GET['id']."'");
$i = 0;
while($print = mysql_fetch_array($fetch)){
if($i == 0){
echo $print['Subject'];
$i++;
}
<table>
<th><?=$print['From']?>, <?=$print['DateSent']?></th>
<tr><td><?=$print['Message']?></td></tr>
</table>
}
If I understand your question correctly, I think you've got the right idea. I'm guessing you want to print something extra the first iteration (like maybe column headers using the array keys)?
$cnt= 0;
while($row = mysql_fetch_assoc($res)) {
if(0 == $cnt++) {
// first iteration only
}
// all iterations
}
Or, if I'm totally off a better description of what you're trying to do and the real world situation would help.
Have you thought about do...while? It has all of the benefits of while, plus it allows for code to conditionally happen before the first iteration.
$res = mysql_fetch_array( $resource );
// run the magical run once query/functionality/bunnies/whatever
// Hey, I'm tired. Let there be bunnies.
do
{
// put the regular while loop constructs in here;
}
while( $res = mysql_fetch_array( $resource ) );
$rs = mysql_query("SELECT * FROM tbl");
$row = mysql_fetch_array($rs);
do {
echo $row['column_name'];
} while($row = mysql_fetch_array($rs));
I don't know if this is what you need. Hope this one helps. =]
Related
Is there a way to make the code below cleaner?
I wanted to access the rows of $query4week like this: $query4week[0].
But mysqli_query() returns an Object on which I don't know how to access its particular rows. So, using fetch_array and a for loop I decided to create my own index.
$sql2 = "SELECT * FROM meals ORDER BY RAND() LIMIT 7";
$query4week = mysqli_query($con, $sql2) or die(mysqli_error($con));
for ($i = 0; $result = mysqli_fetch_array($query4week, MYSQLI_ASSOC); $i++)
{
$meal4week[$i] = $result['meal'];
}
I am still learning PHP and yet quite weak with OOP topics, please be patient :-)
Do it in this way
$i = 0;
while ($result = mysqli_fetch_array($query4week, MYSQLI_ASSOC))
{
$meal4week[$i] = $result['meal'];
$i++;
}
should work.
You shouldn't need a for loop if your fetching an associative array.
$i = 0;
while($row = mysqli_fetch_array($query4week, MYSQLI_ASSOC))
{
$meal4week[$i] = $row['meal'];
$i++;
}
There are already some perfectly reasonable answers here, but this is a little long for a comment. If all you are creating is a numerically indexed array starting with index 0, you don't need to explicitly define the index.
while($row = mysqli_fetch_array($query4week, MYSQLI_ASSOC)) {
$meal4week[] = $row['meal'];
}
should work just fine. No $i necessary.
mysqli_query returns you a resource which represents the query result. You need to use the mysql_fetch_* functions to iterate over the result row by row. So yes, you need some kind of loop, if you are interested in more than the first row.
I loop trough the rows with this code:
while ($row = $result->fetch_assoc()) {
//...
}
But how is it possible before the mysqli_fetch_assoc to check if there will be a next record, or not? I mean, like: $result->hasNext()
Check the total number of returned rows using $mysqli->num_rows, then compare it to a counter in your loop that you increment with each loop iteration.
$row_cnt = $result->num_rows;
$loop_ct = 0;
while($row = $result->fetch_assoc()) {
if(++$loop_ct < $row_cnt) {
//do something
}
}
I prefer working efficiently and don't write extra code if it isn't needed. The following will work just fine:
$cnt = $result->num_rows;
while($row = $result->fetch_assoc()){
//....
$cnt--;
if($cnt == x){ //Where x is the number you want
//....
}
}
You're doing a while loop until you don't have any rows left, so the question is do you really need a test or do you just run the code you want at the end of your loop? If you need to test inside whether there will be a next row, you could do this:
$row = $result->fetch_assoc();
while (1) {
...
if (!$row = $result->fetch_assoc()) {
// No next row
break;
}
}
Which is pretty similar to what you're doing now.
Consider the code you posted
while ($row = $result->fetch_assoc()) {
//...
}
It is already doing that. check out the docs for mysqli_result::fetch_assoc, the while loop will break if $result->fetch_assoc() returns NULL. You don't need to manually check anything.
Either you can go with #McWayWeb or you can try this function mysqli_next_result().
Read it's manual here:- http://php.net/manual/en/mysqli.next-result.php
using PDO, I receive 1+ rows and turn them into an array like this:
while($row = $car_sales->fetch(PDO::FETCH_ASSOC)){
$car_id_array[] = $row["car_id"];
$car_type_array[] = $row["car_type"];
$dealer_id_array[] = $row["dealer_id"];
$buyer_id_array[] = $row["seller_id"];
}
I'm trying to simply "mix" each level of the array to act as a unit and go down the foreach loop together, submitting the $q query in order. In other words, something like this:
foreach($dealer_id_array as $dealer_id) {
if ($car_type=='new') {
if ($dealer_id==$buyer_id){
$q = 'UPDATE car_sales SET new_cars=new_cars+1 WHERE dealer_id=:dealer_id';
} else if ($dealer_id!=$buyer_id){
$q = 'UPDATE car_sales SET new_cars=new_cars-1 WHERE dealer_id=:dealer_id';
} else if ($car_type=='old') {
if ($dealer_id==$buyer_id){
$q = 'UPDATE car_sales SET old_cars=old_cars+1 WHERE dealer_id=:dealer_id';
} else if ($dealer_id!=$buyer_id){
$q = 'UPDATE car_sales SET old_cars=old_cars-1 WHERE dealer_id=:dealer_id';
}
$car_update = $dbhandle->prepare($q);
$car_update->execute(array(':dealer_id' => $dealer_id));
}
The loop should run with the first array values if there is only one value retrieved from the while loop. If there are more, the foreach should run as many times as there are dealer_ids from the while loop, while respecting the order. This example won't work, but I'm looking for possible solutions to solve this issue correctly. What do you think would be the most efficient way to do this?
I might be misunderstanding you, but I believe if you just replaced your foreach loop with a for loop, and counted one of the arrays you would solve your issue:
for($i = 0; $i < count($dealer_id_array); $i++) {
and then simply using $i to access the correct item in your arrays:
$car_type_array[$i];
But having said that, I don't really see the point of the initial four arrays in the first place. Could you not just directly execute the code inside the foreach loop straight inside the while loop in the first place?
EDITED: to fix code example
I tried to make the title of this most the most descriptive as possible, as I don't know how to do this... I know the best way will be value storage in some form of array.
My question is this, I have this query where I need to pic the tag name and the correspondent id for a later comparison and use ($tag_nome is collected by $_GET):
$resultado2 = mysql_query("SELECT tag.tag_nome, rel_frasetag.id_tag
FROM tag, rel_frasetag
WHERE rel_frasetag.id_tag = tag.id_tag AND
rel_frasetag.id_frase='$id_frase'") or die(mysql_error());
while($res2 = mysql_fetch_array($resultado2))
{
$tag_nome2 = utf8_encode($res2['tag_nome']);
$id_tag = $res2['id_tag'];
}
I already tried some things like array_push() but couldn't get it to work.
At the end of this snippet I'm comparing $tag_nome2 against $tag_nome to see if they match. If so, it will echo one link with the corresponding $tag_nome2 and $id_tag, and if not will echo pretty much the same thing, with a different class on the link.
My best guess as far as what you want to do is the following:
if( $tag_nome2 == $id_tag )
{
// do something
}
else
{
// no match
}
Perhaps though, you're saying your variable names are being overwritten? You're inside of a while loop, so the values they'll ultimately receive will be that of $res2[] at the end of the last iteration of your loop.
And if you're saying you want to save your rows for later, you can do:
$holder = array();
$res = mysql_query("");
while( $row = mysql_fetch_assoc($res) )
{
$holder[] = $row;
}
print_r($holder);
I have found a confusing thing in a php script I am writing to generate some javascript. Here it is below, slightly simplified.
The second while loop won't run unless I comment out the entire first while loop. Can anyone explain why? Many thanks.
<?php
$listid = 2; //DEMO ONLY
$result1 = mysql_query("SELECT words.wid,words.wordmd5,words.word FROM words,instances WHERE words.wid = instances.wid AND instances.lid = \"$listid\"");
$result1copy = $result1;
$count1 = 1;
while( $row = mysql_fetch_object( $result1 ) )
{
print "words_left[$count1] = \"".$row->word."\";\n";
//Increment the array counter (starts at 1)
$count1++;
}
?>
//Some javascript
<?php
$count2 = 1;
while( $row = mysql_fetch_object( $result1copy ) )
{
print "
$count2 then $row->wordmd5
";
$count2++;
}
?>
You haven't copied the result set, you've just ended up with two references to the result set. The underlying result set object is the same regardless of which reference to it you use, and so you've already processed all of the records by the time the second loop begins.
You probably want to switch to using a single loop, and keeping track of the data you want to output in an array. Alternately, as Flinsch points out, you could use mysql_data_seek to return to the beginning of the result set, since you're using a buffered query.
In addition to what T.J. Crowder already said, a mysql_data_seek($result1, 0) would do the job between the two loops, to reset the internal iterator.