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.
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'm working on pagination, and for some reason I cannot use mysql_fetch_array to loop through a result more than once.
//both $page and $imagesPerPage != 0
$offset = $page * $imagesPerPage
while ($row = mysql_fetch_array($result)) {
$total_images++;
}
echo $total_images;
//echos correct amount
$row = null;
$images_to_offset = 0;
while ($row = mysql_fetch_array($result) && $images_to_offset < $offset) {
$images_to_offset++;
}
echo $images_to_offset;
//echos 0... which is wrong
Should I be using a different php function to get row data in a database?
Thanks!
This is the error
while ($row = mysql_fetch_array($result)) {
$total_images++;
}
once you fetched the array the array pointer set to the end.
use this
$total_images=mysql_num_rows($result);
and
$images_to_offset=mysql_num_rows($result);
OR
To reset the position of pointer Use mysql_data_seek(). it moves internal result pointer
If you wish to start fetching from the beginning after you've already fetched, you'll need you use mysql_data_seek().
Also, please note that the mysql line of functions have been deprecated, and the community is encouraging use instead of MySQLi or PDO_MySQL lines of functions.
You could point the pointer back to the first row with mysql_data_seek.
mysql_data_seek($result, 0);
Also see: http://ca2.php.net/manual/en/function.mysql-data-seek.php
You have to 'rewind' the array, by using the mysql_data_seek function:
$offset = $page * $imagesPerPage
while ($row = mysql_fetch_array($result)) {
$total_images++;
}
echo $total_images;
//echos correct amount
$row = null;
mysql_data_seek(); // <-- rewind to the beginning
$images_to_offset = 0;
while ($row = mysql_fetch_array($result) && $images_to_offset < $offset) {
$images_to_offset++;
}
echo $images_to_offset;
mysql_fetch_array not only returns an array that corresponds to the fetched row, it also moves the internal data pointer ahead.
There are more than one way of dealing with this, the most obvious is to "park" your result in an array itself and then work from there. Or query 2 times. Or use mysql_data_seek. In your case, maybe mysql_num_rows is more appropriate, since your code indicates you only want to know how many rows you have to iterate through, and thats what this function is there for.
Whatever decide, keep in mind that use of the mysql extension is discouraged. Instead, the MySQLi or PDO_MySQL extension should be used.
Try using mysql_num_rows() , that way you don't have to iterate the $result twice which is giving you error in the second loop as you have to reset the result pointer. So do it like this which only iterates once:
//both $page and $imagesPerPage != 0
$offset = $page * $imagesPerPage
$total_images = mysql_num_rows($result);
echo $total_images;
//echos correct amount
$row = null;
$images_to_offset = 0;
while ($row = mysql_fetch_array($result) && $images_to_offset < $offset) {
$images_to_offset++;
}
echo $images_to_offset;
As a side note, you should try to migrate to MySQLi or PDO_MySQL to access mysql as the interface you are using is now deprecated, see the red box in http://es.php.net/manual/en/function.mysql-num-rows.php
You can only loop through the results array once, after that they effectively 'disappear'. the way to loop over the results multiple times is to store them into a new array during the first loop, then loop over the new array as many times as you want...
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);
For whatever reason, I need to go through a MySQL result set twice. Is there a way to do it?
I don't want to run the query twice and I don't want to have to rewrite the script so that it stores the rows somewhere and then reuses them later.
This is how you can do it:
$result = mysql_query(/* Your query */);
while($row = mysql_fetch_assoc($result)){
// do whatever here...
}
// set the pointer back to the beginning
mysql_data_seek($result, 0);
while($row = mysql_fetch_assoc($result)){
// do whatever here...
}
However, I would have to say, this doesn't seem the right way to handle this. Why not do the processing within the first loop?
For mysqli you should do the following;
$result= $con->query($sql); // $con is the connection object
$result->data_seek(0);
Try whether mysql_data_seek() does what you need.
mysql_data_seek() moves the internal
row pointer of the MySQL result
associated with the specified result
identifier to point to the specified
row number. The next call to a MySQL
fetch function, such as
mysql_fetch_assoc(), would return that
row.
row_number starts at 0. The row_number
should be a value in the range from 0
to mysql_num_rows() - 1. However if
the result set is empty
(mysql_num_rows() == 0), a seek to 0
will fail with a E_WARNING and
mysql_data_seek() will return FALSE
Alternative to the data seek is to store the values into an array:
$arrayVals = array();
$result = mysql_query(/* Your query */);
while($row = mysql_fetch_assoc($result)){
$arrayVals[] = $row;
}
// Now loop over the array twice instead
$len = count($arrayVals);
for($x = 0; $x < $len; $x++) {
$row = $arrayVals[$x];
// Do something here
}
$len = count($arrayVals);
for($x = 0; $x < $len; $x++) {
$row = $arrayVals[$x];
// Do something else here
}
I confess I haven't tried this, but have you tried after your first iteration
mysql_data_seek($queryresult,0);
to go to the first record?
You can use mysql_data_seek to move the internal pointer to the beginning of the data set. Then, you can just iterate through it again.
Well, you could always count the number of rows you read, and then do something like this:
if (rownumber == mysql_num_rows($result)) { mysql_data_seek($result, 0); }
Don't know why you would need to, but there it is.
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. =]