<?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"];
}
Related
I'm trying to run if and else if inside a while loop in my PHP code.
The code looks like this:
<?php
$sql = "SELECT * FROM table ORDER BY id";
$query = mysqli_query($db_conx, $sql);
$productCount = mysqli_num_rows($query);
if ($productCount > 0) {
while($row = mysqli_fetch_array($query, MYSQLI_ASSOC)){
$deviceType = $row["deviceType"];
if($deviceType == 'iPhone' || $deviceType == 'iPad'){
echo 'IOS';
}else if($deviceType == 'Android'){
echo 'Android';
}
}
} else {
}
?>
The code above works (sort of) but not as I was expecting it.
To give you an example, lets say I have 2 rows in MYSQL database.
like this:
id deviceType
1 Android
2 iPhone
when i run my PHP code above, I get this echo-ed on my page:
IOS
IOS
Android
Android
BUT I only have 2 rows in the database so the result should be:
IOS
Android
Could someone please advise on this issue?
This question is clearly misrepresenting your actual code/data.
When your database table has 2 rows, but you are receiving 4 rows then the onus is not on the fetching function, but on your query or database table data.
If your actual query is as posted in your question, then your table data contains more than two rows.
If your actual query is different from what you posted (say, joining the table with a copy of itself), then your data is fine and your query is failing you.
Regardless of if you are using mysqli_fetch_array($result), mysqli_fetch_array($result,MYSQLI_ASSOC), or mysqli_fetch_assoc($result), your while() loop will only do one iteration for each row of data.
The difference in resultset fetching functions:
mysqli_fetch_array($result):
array(0=>'1', 'id'=>'1', 1=>'Android', 'deviceType'=>'Android') // 1 row w/ 4 elements
array(0=>'2', 'id'=>'2', 1=>'iPhone', 'deviceType'=>'iPhone') // 1 row w/ 4 elements
mysqli_fetch_array($result,MYSQLI_ASSOC), or mysqli_fetch_assoc($result):
array('id'=>'1', 'deviceType'=>'Android') // 1 row w/ 2 elements
array('id'=>'2', 'deviceType'=>'iPhone') // 1 row w/ 2 elements
I will rewrite your code and implement some good practices:
if($result=mysqli_query($db_conx,"SELECT `deviceType` FROM `table` ORDER BY `id`;")){
if(mysqli_num_rows($result)){
while($row=mysqli_fetch_assoc($result)){
echo ($row["deviceType"]=="Android"?"Android":"IOS"); // inline condition is a personal preference
}
}else{
echo "No rows in `table`.";
}
}
Only bother declaring a variable if you will use its value more than once (*or if it dramatically improves readability to separate it from its single use.)
So that your variable names are intuitive, name your query variable $sql or $query; and name your query's result variable $result.
Only SELECT columns that you intend to use; * is unnecessary for your case.
Backtick ` wrapping is not required on column and table names, but doing so will avoid any potential clashes with MySQL keywords.
Perform a conditional check and declare the $result variable as false or [resultset] in a single step.
Always check that $result is true before calling any functions that access the resultset. (e.g. mysqli_num_rows() and mysqli_fetch_assoc()).
if(mysqli_num_rows($result)){ will check for a non-falsey value -- I mean 0 equates to false and anything greater than 0 will be true.
Your code appears to be perfectly fine. However, instead of the expected output, you get more items than needed. If I am not mistaken, this means that you have duplicate deviceType in your database table. $productCount probably has a value of 4. You can get two values if you use this query instead:
SELECT DISTINCT `deviceType` FROM `table` ORDER BY `id`
but while this should fix the output you get, your data will still hold duplicates, so you might want to look into the data of your table and into the way it was created, find out and fix the problem.
the answer is very simple you are fetching the results twice with the while loop change this line
while($row = mysqli_fetch_array($query, MYSQLI_ASSOC)){
to
while($row = mysqli_fetch_assoc($query)){
then it will work right, you can see buy the order iPhone iPhone android android that is doing it twice instead of once per loop
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 continue to struggle with array! This is probably easy to answer.
I'm retrieving a data set from MYSQL w/ PHP. I get an array that has the 1st row (ala the mysql_fetch_array). Typically I would just loop through this and get each value, but in this case I'm already in the middle of a loop and I need to find out if a particular value exists in the full data set (which will be more than 1 row).
I figured I could just loop through and put all the values into an array with something like:
$query = "SELECT MapId FROM Map Where GameId = $gl_game_id";
$result_set = mysql_query($query, $connection);
confirm_query($result_set);
$map_set = array();
while($row = mysql_fetch_assoc($result_set)) {
$map_set[] = $row;
}
When I print_r this, I do in fact get the full data set (e.g. all rows of MapId from table Map).
So now, when I go to look in there and see if a value (that is coming out of this other loop) exists, it won't find it.
So my code looks like:
if (in_array($i, $map_set)) {
echo "yes, it's there baby!";
}
But it doesn't work. I tried hard coding the array, and that does in fact work. So there is simply something wrong with the way I'm constructing my array that this function doesn't like it.
if (in_array($i, array(40,12,53,65))) {
echo "yes, it's there baby!";
}
arrrg... I do hate being a noobie at this.
Function mysql_fetch_assoc returned array.
If you make print_r($map_set) then you will see that is 2-dimension array. Sure in_array not worked.
Just replace $map_set[] = $row; by $map_set[] = $row["MapId"]; and then try again.
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.
This would helps me a lot to understand how does loop works
Let say i've database table my_table (id,words) and here is example of database
INSERT INTO `my_table` VALUES (1,'hello manal');
INSERT INTO `my_table` VALUES (2,'nice manal');
INSERT INTO `my_table` VALUES (3,'pretty manal');
now imagine for 100,000 entries (huge) and i want to replce the word manal to jack and giving me results every line changed one by one
i'll use
$conn = mysql_connect('localhost','USER','PASS') or die(mysql_error());
mysql_select_db('my_table',$conn);
$sql = "SELECT * from my_table";
$result = mysql_query($sql,$conn);
while ($row = mysql_fetch_array($result)){
$old = $row['words'];
$id = $row['id'];
$new="jack";
$new = str_replace("manal", "$new", $old);
echo $new;
}
The loop
by that code it will works all at once which is impossible to my hosting server to apply all so i want to make it as loop ! i mean it will change the 1st database line then gives me the results echo $new; then change the 2nd database line then gives the results echo $new; and so on with no stop till last line.
so my important part is getting the results one by one ~thanks
The problem will be that your output is being buffered which is why you see all the results at the same time (at the end of the execution of the script).
You could add ob_flush(); flush(); within the loop before echo $new; an see if that helps. Regardless, the above example is going to execute pretty quickly so it isn't exactly going to be easily readable!
You better do this replace in the database itself and then you just print it out.
$sql = "UPDATE my_table SET words = REPLACE(words, 'manal', 'jack')";