$allUsersResult = mysql_query("SELECT * FROM users");
// the purpose of this line was to grab the first row for use
// separately in a different area than the while loop
$user = mysql_fetch_assoc($allUsersResult);
while($users = mysql_fetch_assoc($allUsersResult)){
// the first row is not available here
}
So is this a bug or is it my fault for doing it wrong?
PS: this is only for example. I'm not using both $user and the while loop right next to each other like this, they are used in different places in the script.
You need to drop
$allUsers = mysql_fetch_assoc($allUsersResult);
It's taking your first result row.
Answer to new question: No. It is not a design flaw in PHP. It's a flaw in your program design. You need to rethink what you are doing.
Why do you need the first value separated out? Are you relying on it to be a specific row from your table all of the time? If you alter your table schema it's very possible that the results will be returned to you using some other sorted order.
Perhaps if you tell us what you are trying to do we can give you some design suggestions.
It is your fault. By calling $allUsers = mysql_fetch_assoc($allUsersResult); first, you already fetch the first row from the result set. So just remove that line, and it should work as expected.
edit: Per request in comment.
$user = mysql_fetch_assoc($allUsersResult);
if ( $user ) // check if we actually have a result
{
// do something special with first $user
do
{
// do the general stuff with user
}
while( $user = mysql_fetch_assoc($allUsersResult) );
}
Which is considered as bad code by some IDEs (two statements in one row). Better:
$allUsersResult = mysql_query("SELECT * FROM users");
$user = mysql_fetch_assoc($allUsersResult);
while($user){
// do stuff
doStuff($user)
// at last: get next result
$user = mysql_fetch_assoc($allUsersResult)
}
When you use mysql_fetch_assoc(), you are basically retrieving the row and then advancing the internal result pointer +1.
To better explain, here is your code:
$allUsersResult = mysql_query("SELECT * FROM users");
//Result is into $allUsersResult... Pointer at 0
$user = mysql_fetch_assoc($allUsersResult);
// $user now holds first row (0), advancing pointer to 1
// Here, it will fetch second row as pointer is at 1...
while($users = mysql_fetch_assoc($allUsersResult)){
// the first row is not available here
}
If you want to fetch the first row again, you do not need to run the query again, simply reset the pointer back to 0 once you have read the first row...
$allUsersResult = mysql_query("SELECT * FROM users");
//Result is into $allUsersResult... Pointer at 0
$user = mysql_fetch_assoc($allUsersResult);
// $user now holds first row (0), advancing pointer to 1
// Resetting pointer to 0
mysql_data_seek($allUsersResult, 0);
// Here, it will fetch all rows starting with the first one
while($users = mysql_fetch_assoc($allUsersResult)){
// And the first row IS available
}
PHP Documentation: mysql_data_seek()
I'll go ahead and answer my own question on this one:
$allUsersResult = mysql_query("SELECT * FROM users");
// transfer all rows to your own array immediately
while($user = mysql_fetch_assoc($allUsersResult)){
$allUsers[] = $user;
}
// use first row however you like anywhere in your code
$firstRow = $allUsers[0];
// use all rows however you like anywhere in your code
foreach($allUsers as $user){
// do whatever with each row ($user). Hey look they're all here! :)
}
Related
<?php
$connect = mysqli_connect("localhost", "root", "", "hempbag_db") or die("Connection failed");
$query= "Select * from tbl_sales";
$ress = mysqli_query($connect, $query);
$result = mysqli_fetch_array($ress);
foreach($result as $a)
{
echo $a['ID']; // This doesnt print although i used fetch array
}
foreach($ress as $a)
{
echo $a['ID']; // This works why???? This variable has only query run
}
?>
Why does the upper foreach does not run and lower one does? Can anyone explain please?
When you run a query, it returns a result:
$ress = mysqli_query($connect, $query);
var_dump($ress); // You will see it's a result.
At this point $ress just contains the result of what you just queried. Think of it like this:
You goto the warehouse, and you make and order for 1000 boxes of crackers. She heads to the back, and gets your boxes ready, and comes back and hands you a piece of paper with the order number. (This is $ress). Now, you can't loop through that, you can't do anything with that.
You now take that piece of paper, and you hand it to your assistant, and you say you want to get all the crackers on your trucks (This is now mysqli_fetch_array()). Your assistant goes, fetches it, and returns you the crackers.
Simply put, mysqli_query just returns an object like Result#1. From Result#1, mysql can tell you how many rows were returned mysql_num_rows(Result#1), or get actual data if it was a select query: mysqli_fetch_array(Result#1).
Now onto the reasoning: Performance. Let's say you didn't want 1000 crackers, you just wanted to know if they had 1000 crackers. If she came back with all the boxes of crackers and you had to count them yourself, it would be much more difficult. Instead, with that piece of paper, she can determine how many boxes you were able to order. Less data being transferred, and much more efficient.
Just a small note, in later versions of php, they made it so the result is iterable, meaning that if you try and loop through it, it will automagically call mysqli_fetch_array on that result, and return you the results.
Additionally, mysql_fetch_array will return one row from the database, and is not able to be looped through via foreach. Perhaps you were thinking of mysqli_fetch_all? This returns all rows and can be looped through (Although is a bit less performant than using a while loop with mysqli_fetch_array)
$ress = mysqli_query($connect, $query);
This line returns a result set which is Traversable. So your second foreach works fine.
whereas the following line (mysqli_fetch_array) gets one row at a time and makes it an array.
$result = mysqli_fetch_array($ress); // Suppose you have 3 rows, Now cursor is at row 1
echo $result["ID"]; // this will print FIRST row's ID
$result = mysqli_fetch_array($ress); // Now cursor is at row 2
echo $result["ID"]; // this will print SECOND row's ID.
$result = mysqli_fetch_array($ress); // Now cursor is at row 3
echo $result["ID"]; // this will print THIRD row's ID.
To echo all IDs
while($result = mysqli_fetch_array($ress)) {
echo $result["ID"];
}
I am trying to run a query to my mysql database through php and and am trying to get all the resulting rows. I also have to compare every row to the next row returned. I am trying to do this by setting the result variable to another temporary variable and calling mysqli_fetch_assoc() on that so that the while loop runs again for the next row. But what happens is that when I try to use mysqli_fetch_assoc() even on the other variables, somehow mysqli_fetch_assoc($result) also progresses to the next of the next row when while($row = mysqli_fetch_assoc($result)) goes to next iteration.
Here is the code example to illustrate this :
$query = "SELECT * FROM records ORDER BY num ASC;";
if($result = mysqli_query($conn, $query))
{
while($row = mysqli_fetch_assoc($result))
{
$temporaryresult = $result;
$rowtwo = mysqli_fetch_assoc($temporaryresult);// this makes mysqli_fetch_assoc($result) skip the next row which is unwanted
}
}
So how can I keep mysqli_fetch_assoc($result) from moving forward when I call mysqli_fetch_assoc($temporaryresult) ?
Any help would be appreciated.
am trying to do this by setting the result variable to another temporary variable and calling mysqli_fetch_assoc() on that so that the while loop runs again for the next row
It doesn’t work that way. Just because you assigned the resource id to a second variable, doesn’t mean that you now have a second result set that you could operate on separately. Both variables refer to the same resource id. Fetching a row will still move the row pointer of the “original” data set.
I also have to compare every row to the next row returned
Most likely, you are making things harder on yourself by trying to look ahead. Stuff like this is usually easier done when you look at the previous row instead. That one you have fetched already - so you don’t need to do an additional fetch now that would mess with the row pointer.
Pseudo code example:
$prevRow = null;
while($row = fetch(...)) {
if($prevRow) { // for the first row, this will still be null, so we only
// start comparing stuff when that is not the case
// compare whatever you need to compare here
}
...
$prevRow = $row;
}
After #CBroe's answer, I tried to solve this problem while still trying to look forward. I achieved this by storing the rows returned by the database and then looping through them. This makes it very easy too look ahead in the rows returned while avoiding the complexity of changing your code to look backwards.
$array = array();
// look through query
while($row = mysql_fetch_assoc($query)){
// add each row returned into an array
$array[] = $row;
}
Now, looping through these rows,
$i = 0;
for(;$i<count($array)-1;$i++)
{
if($array[$i]['somecolumn']==$array[$i+1]['anothercolumn'])//compare this column to another column in the next row
{
// do something
}
}
This successfully solved my problem. I hope it helps anyone stuck in the same position I was in.
I'm trying to create a while loop in PHP which retrieves data from a database and puts it into an array. This while loop should only work until the array its filling contains a certain value.
Is there a way to scan through the array and look for the value while the loop is still busy?
to put it bluntly;
$array = array();
$sql = mysql_query("SELECT * FROM table");
while($row = mysql_fetch_array($sql)){
//Do stuff
//add it to the array
while($array !=) //<-- I need to check the array here
}
You can use in_array function and break statement to check if value is in array and then stop looping.
First off, I think it'd be easier to check what you're filling the array with instead of checking the array itself. As the filled array grows, searching it will take longer and longer. Insted, consider:
$array = array_merge($array, $row);
if (in_array('ThisisWhatIneed', $row)
{
break;//leaves the while-loop
}
However, if you're query is returning more data, consider changing it to return what you need, only process the data that needs to be processed, otherwise, you might as well end up with code that does something like:
$stmt = $db->query('SELECT * FROM tbl');
while($row = $stmt->fetch(PDO::FETCH_ASSOC))
{
if ($row['dataField'] === 'username')
{
$user = $row;
break;
}
}
WHERE could help a lot here, don't you think? As well taking advantage of MySQL's specific SELECT syntax, as in SELECT fields, you, need FROM table, which is more efficient.
You may also have noticed that the code above uses PDO, not mysql_*. Why? Simply because the mysql_* extension Is deprecated and should not be used anymore
Read what the red-warning-boxes tell you on every mysql* page. They're not just there to add some colour, and to liven things up. They are genuine wanrings.
Why don't you just check each value when it gets inserted into the array? It is much more efficient than iterating over the whole array each time you want to check.
$array = array();
$stopValue = ...
$sql = mysql_query("SELECT * FROM table");
while($row = mysql_fetch_assoc($sql)){
array_push($array,$row['column']);
if($row['column'] == $stopValue){
// The array now contains the stop value
break;
}
I am retrieving a couple of tables from a MSSQL database, which I am then running through to obtain order information from.
My code looks like this:
while($row = sqlsrv_fetch_array($orderResult))
{
......code........
..................
while($statusRow = sqlsrv_fetch_array($statusResult))
{
....code....
}
....code....
}
Now my problem is that after the second loop runs through, it never runs again. And I need it to run every time the first loop runs.
Is there anything I can do to reset that second loop to run again?
Thank you in advance. Any help or a push in the right direction will be very helpful.
Read about the other parameters in sqlsrv_fetch_array()
You can do something like this to reset
// reset, and get first row
$row = sqlsrv_fetch_row($result, SQLSRV_FETCH_BOTH, SQLSRV_SCROLL_FIRST);
// get second (and nth row) normally
$row = sqlsrv_fetch_row($result);
Alternatively, I think you could benefit from doing a JOIN in your query to return a single result. Merging results manually like this seems a little hackish.
I had a similar problem when calling a stored proc from a database that returned multiple result sets. I found Macek's answer didn't work for me, but another answer did:
$resultSet = array();
$isNotLastResult = true;
$i = 0;
while (!is_null($isNotLastResult))
{
$resultSet[$i] = array();
while ($row = sqlsrv_fetch_array($result, SQLSRV_FETCH_ASSOC))
{
$resultSet[$i][] = $row;
}
$isNotLastResult = sqlsrv_next_result($result);
$i++;
}
print_r($resultSet);
PS: I gave you an up arrow to counteract your down arrow. You asked a question I spent quite a bit of time looking for the answer to. Good question!
Use the following to reset the pointer:
sqlsrv_fetch_array ($Res, SQLSRV_FETCH_ASSOC, SQLSRV_SCROLL_ABSOLUTE, -1);
Then use the same code as before to loop through the result set. sql_fetch_array appears to increment the pointer after retrieving the data. Requesting the -1 record retrieves nothing but then sets the pointer to 0 which is the first record.
are you sure your second loop got results for a second run ? maybe, if your $statusResult depents on your $row and your $row has just entries for the first loop you should insert some pseudo-entries to your db.
the second loop should refresh itself in the next "big" loop cause the whole inner block will be destroyed at the end of the big block and will be (fully) rebuild at the next entry.
I have a mysql query:
$a=mysql_query("SELECT id FROM table1 WHERE p2='fruit' LIMIT 1");
This will only ever return one result or none.
I'm trying to first count the results, then if it 1, to pass the returned id to a variable.
Question: If I do
$results=count(mysql_fetch_assoc($a));
to count the number of rows returned, can I still do later
while($row = mysql_fetch_array($a)){
$id=$row['id'];
}
or will the first delete the array somehow???
Is their a better way to do all this?
You really not need to do anything if there is one row or null
Consider below code it will set id value if there is 1 row fetched otherwise it will be null
$id=''
while($row = mysql_fetch_array($a)){
$id=$row['id'];
}
No count needed.
$results=count(mysql_fetch_assoc($a));
does not count the number of rows as mysql_fetch_assoc returns one row. I believe you're looking for mysql_num_rows:
$results = mysql_num_rows($a);
$num_rows = mysql_num_rows($a);
You can then do an IF statement on this and later do a while loop on the fetched array
Have you tried mysql_num_rows ??
http://php.net/manual/en/function.mysql-num-rows.php
What happens when using:
while($row = mysql_fetch_array($a)){
$id=$row['id'];
}
it is just like reading a file,every time mysql_fetch_array($a) is called the next line is parsed untill it reaches the end of the file. A cursor of some sort is known in the background. Meaning that if you would enter by hand
//backgroundCursor = 0
$row = mysql_fetch_array($a)
//backgroundCursor = 1
$row = mysql_fetch_array($a)
//backgroundCursor =2
$row = mysql_fetch_array($a)
//backgroundCursor = 3
The while instruction just automates the stuff.
mysql_fetch_array increases the background cursor at every call so if you call it twice it will not give you the same line.
To get a clear view on this read something about reading from a file line by line.
No you cannot as each call to mysql_fetch_assoc() loads a new row, if there is any. You could indeed assign both variables at once:
$results=count($row = mysql_fetch_assoc($a));
but
But mysql_fetch_assoc($a)) returns false and as the result of count(false) is 1 this will not tell you anything. Besides, if there is no row all you really need is $row = mysql_fetch_assoc($a) and test if ($row) {...}.