after searching a bit I've found posts in the same vein, but nothing thats specifically helpful to my problem.
I'm slogging through my code updating mysql to mysqli, and I'm hitting a snag on dumping search results into vars.
With a while loop I process each row and dump the fields into vars for display, then repeat until the resulting rows have all been displayed (basic search engine results)
My original code has the following var types (I'll show one for convenience)
$title = mysql_result($rs,$i,"title");
"rs" is the con and query, i is the row number, "title" is the field name
I see there are a few methods in the manual and mysqli_data_seek seems to be the correct route here, but I'm blowing it on parameters according to my editor (call uses 2 parameters and I'm using 3)
$title = mysqli_data_seek($rs,$i,"title");
I have 18 of these vars in the while loop, how can I make this work correctly? (procedural style)
There is no such method as mysql_result within the MySQLi-library. So you have to do it with one of the alternatives. Either run
$allData = mysqli_fetch_all($rs, MYSQLI_ASSOC); // Has to be run only once for the result!
// And access data via
$title = $allData[ $i /* row-number */ ]['title'];
// Or (you didn't provide your current loop)
foreach($allData as $i => $row) {
$title = $row['title'];
}
Or run
mysqli_data_seek($rs, $i); // Set pointer in mysqli to row-nr $i
$row = mysqli_fetch_assoc($rs);
$title = $row['title'];
Or run (most preferable solution I guess, but you didn't provide your current loop):
// Loop over all rows in the result-set
while($row = mysqli_fetch_assoc($rs)) {
$title = $row['title'];
}
Related
With php ibase, ibase_query fetches the relation, several functions can then fetch rows from that relation, but all these functions extract the next row.
In Delphi I have the ability to return to the first row (DataSet.First;) - is there any equivalent in PHP ibase?
I could of course re-query the database, but this seems a waste of resources if the original relation is still accessible.
Example code:
$table = ibase_query($sql);
$row = ibase_fetch_object($table);
while (!empty($row))
{
echo $row->ENTRYNO.'<br>';
$row = ibase_fetch_object($table);
}
//The missing functionality
$table.First;
//or maybe
$row = ibase_fetch_object($table,first);
//in which case of course the following line would be redundant
$row = ibase_fetch_object($table);
while (!empty($row))
{
//process record
$row = ibase_fetch_object($table);
}
The ibase/firebird-php driver is only able to fetch forward. If you want to consult earlier rows, you will need to store them yourself in some form, or execute the query again.
<?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'm updating some old code that has deprecated MySQL functions. But for some reasons I cannot get all the results from the column. The strange part is that if I run the query directly on the server I get all results fine. So this is an issue with PHP getting the results, not the MySQL server or my query.
Here is the new and old code:
My current updated code:
$sql = "SELECT user, monitor FROM users WHERE `status` = 'y'";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
// This works. It shows all results
echo $row["user"];
// This does not work! Only shows one result:
$account= $row["user"];
}
else {
echo 'No results';
}
When I use that query directly on DB server, I get all results. So the SQL query is correct. I actually also get all results as well in PHP if I echo the row directly like:
echo $row["user"];
But for some reason when I try to use it with a PHP with variable it only lists one user result.
In the past I used this but the mysql_fetch_array function is now deprecated
while ($row = mysql_fetch_array($result)) {
array_push($data, $row["user"]);
}
foreach($data as $value) {
$account = $value
}
I cannot use my previous code anymore as those MySQL functions are obsolete today. I need to write the results into a file and my old method worked fine. The new one using mysqli does not.
Any suggestions?
You just need to add one of these [, and one of these ].
$account[] = $row["user"];
// ^^ right here.
$account= $row["user"]; means you're storing the value of $row["user"] in $account each time the loop executes. $account is a string, and it gets a new value each time.
$account[] = $row["user"]; means you're appending each value of $row["user"] to an array instead.
You should not use array_push for this. It's overkill for appending a single value to an array. And if the array isn't defined beforehand, it won't work at all.
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.
Assuming that the mysqli object is already instantiatied (and connected) with the global variable $mysql, here is the code I am trying to work with.
class Listing {
private $mysql;
function getListingInfo($l_id = "", $category = "", $subcategory = "", $username = "", $status = "active") {
$condition = "`status` = '$status'";
if (!empty($l_id)) $condition .= "AND `L_ID` = '$l_id'";
if (!empty($category)) $condition .= "AND `category` = '$category'";
if (!empty($subcategory)) $condition .= "AND `subcategory` = '$subcategory'";
if (!empty($username)) $condition .= "AND `username` = '$username'";
$result = $this->mysql->query("SELECT * FROM listing WHERE $condition") or die('Error fetching values');
$this->listing = $result->fetch_array() or die('could not create object');
foreach ($this->listing as $key => $value) :
$info[$key] = stripslashes(html_entity_decode($value));
endforeach;
return $info;
}
}
there are several hundred listings in the db and when I call $result->fetch_array() it places in an array the first row in the db.
however when I try to call the object, I can't seem to access more than the first row.
for instance:
$listing_row = new Listing;
while ($listing = $listing_row->getListingInfo()) {
echo $listing[0];
}
this outputs an infinite loop of the same row in the db. Why does it not advance to the next row?
if I move the code:
$this->listing = $result->fetch_array() or die('could not create object');
foreach ($this->listing as $key => $value) :
$info[$key] = stripslashes(html_entity_decode($value));
endforeach;
if I move this outside the class, it works exactly as expected outputting a row at a time while looping through the while statement.
Is there a way to write this so that I can keep the fetch_array() call in the class and still loop through the records?
Your object is fundamentally flawed - it's re-running the query every time you call the getListingInfo() method. As well, mysql_fetch_array() does not fetch the entire result set, it only fetches the next row, so your method boils down to:
run query
fetch first row
process first row
return first row
Each call to the object creates a new query, a new result set, and therefore will never be able to fetch the 2nd, 3rd, etc... rows.
Unless your data set is "huge" (ie: bigger than you want to/can set the PHP memory_limit), there's no reason to NOT fetch the entire set and process it all in one go, as shown in Jacob's answer above.
as a side note, the use of stripslashes makes me wonder if your PHP installation has magic_quotes_gpc enabled. This functionality has been long deprecrated and will be removed from PHP whenever v6.0 comes out. If your code runs as is on such an installation, it may trash legitimate escaping in the data. As well, it's generally a poor idea to store encoded/escaped data in the database. The DB should contain a "virgin" copy of the data, and you then process it (escape, quote, etc...) as needed at the point you need the processed version.