why does only first mysqli_fetch() result gets stored in array - php

I'm new to mysqli prepared statements. I'm trying to store the results in an associative array so that I can use it further. The results get printed properly before appending to the array but when appended only the first entry gets added. what is the mistake in the approach here?
// order_details_table
$order_details = array();
$invoice = 1234;
$stmt = $con->prepare("SELECT `description`,`amount` FROM order_details_table WHERE invoice_no = ?");
$stmt->bind_param("s", $invoice);
$stmt->execute();
$stmt->bind_result($description,$amount);
while($stmt->fetch())
{
print_r($description." ".$amount); //This prints all the entries for the given query
$row['desc'] = $description;
$row['amount'] = $amount;
$order_details += [$row]; //This appends just the first entry
}
print_r($order_details);

You are using array union operator. From PHP docs:
The + operator returns the right-hand array appended to the left-hand array; for keys that exist in both arrays, the elements from the left-hand array will be used, and the matching elements from the right-hand array will be ignored.
Your temporary array has the same key as the array you are collecting into. Both have elements with key 0, so the new row is not added.
To fix it you should use array push operator i.e. [].
while($stmt->fetch())
{
print_r($description." ".$amount); //This prints all the entries for the given query
$row['desc'] = $description;
$row['amount'] = $amount;
$order_details[] = $row; // Append the new row into the array
}
However, I do not recommend such manual approach. mysqli has methods for fetching all the rows at once. You should use fetch_all() instead.
// order_details_table
$invoice = 1234;
$stmt = $con->prepare("SELECT `description`,`amount` FROM order_details_table WHERE invoice_no = ?");
$stmt->bind_param("s", $invoice);
$stmt->execute();
$result = $stmt->get_result(); // Get the result instead of binding
$order_details = $result->fetch_all(MYSQLI_ASSOC);
If you really want to loop on the results one by one and build an array manually then use foreach loop on the mysqli_result object.
// order_details_table
$invoice = 1234;
$stmt = $con->prepare("SELECT `description`,`amount` FROM order_details_table WHERE invoice_no = ?");
$stmt->bind_param("s", $invoice);
$stmt->execute();
$result = $stmt->get_result(); // Get the result instead of binding
$order_details = []; // Instanciate empty array
foreach($result as $row)
{
$newrow['desc'] = $row['description'];
$newrow['amnt'] = $row['amount'];
$order_details[] = $newrow; //This appends just the first entry
}
print_r($order_details);

Related

How to get an Int result from array in PHP /MYSQL

I have written code with the intention of getting an integer quantity but the result am getting is in an array format.How do I convert that from an array to an integer. Am getting the results from a MySQL database...
Here is my code, Instead of it returning an array I need to get the array value that is at that key
function hcQuantiy($db, $isbn)
{
$query = "SELECT num_hardcover from inventory where isbn = :isbn";
$statement = $db->prepare($query);
$statement->bindValue(':isbn', $isbn);
$statement->execute();
$result = $statement->fetchAll(PDO::FETCH_ASSOC);
$statement->closeCursor();
return $result;
}
If you need only one row dont use the method fetchAll which returns an array of rows, use only fetch, which returms an array with one row.
Use PDO::FETCH_NUM for fetch and get the index 0 of the result.
Than convert the result to an int. And there you have your quantity :)
Your code edited:
function hcQuantiy($db, $isbn) {
$query = "SELECT num_hardcover FROM inventory WHERE isbn = :isbn";
$statement = $db->prepare($query);
$statement->bindValue(':isbn', $isbn);
$statement->execute();
$result = $statement->fetch(PDO::FETCH_NUM);
$statement->closeCursor();
return intval($result[0]);
}
You can do accessing the array eg:
while ($row = $statement->fetchAll(PDO::FETCH_ASSOC)) {
echo $row["num_hardcover"] . '<br />;
}

PHP - MySQL Query assigning same row to two different indexes in array

I have a query that is supposed to get two rows of data from a database, a and b. When I vardump inside of the mysqli_stmt_fetch loop, I get the data of a and b and then inside of the loop, I assign it as a member of an array ($Array[] = $result). However, when I then vardump $Array, the data for b is in both indexes of the array.
Expected result is that the data for both a and b are in the array, but there is just two instances of b's data.
Code
if ($Query = mysqli_prepare($MySQLObj, "SELECT x.c, x.d, x.e, x.f, y.g, y.h FROM x INNER JOIN y ON (y.i = x.j) WHERE x.k = 0 OR x.k = 1 ORDER BY x.l ASC LIMIT 10;")) // Prepare Query
{
mysqli_stmt_execute($Query); // Execute query
mysqli_stmt_bind_result($Query, $Data["m"], $Data["n"], $Data["o"], $Data["p"], $Data["q"], $Data["r"]); // Bind result to array elements
while (mysqli_stmt_fetch($Query)) // Fetch result
{
$DataArray[] = $Data; // This doesn't work
//var_dump($Data);
}
mysqli_stmt_close($Query); // Close query
}
var_dump($DataArray);
normal you can not _bind_result to an $Data["m"], $Data["n"], $Data["o"], ... array
you need variables e.g. $Data_m , $Data_n ....
but you can set a $variable like that
$Query->store_result();
$variables = array();
$data = array();
$variables[] = &$Data["m"];
$variables[] = &$Data["n"];
$variables[] = &$Data["o"];
....
call_user_func_array(array($Query, 'bind_result'), $variables);
Update
If you don't want to set $variables[] by hand, try
$meta = $Query->result_metadata();
while($field = $meta->fetch_field())
$variables[] = &$Data[$field->name];
Just change $DataArray[] = $Data; into $DataArray[] = &$Data; and thats all.

How to fetch 2 times in MYSQL PDO without FETCHALL

I have this sample query:
$STH = $DBH->query("SELECT id FROM table");
I want to get the first row and then loop and display all rows. So I use the following to get the first row:
$STH->setFetchMode(PDO::FETCH_ASSOC);
$first_row = $STH->fetch();
$first_row = $first_row['id'];
I use while loop to display all rows again:
while ($list = $STH->fetch()) {
$id = $list['id'];
echo $id;
}
Now the while skips the first row and I want it to be displayed. Is there an equivalent to mysql_data_seek to reset the pointer again to the first row? I know fetchall can be used but it's bad on memory and wasteful. I could also run the query and limit to 1 but this is not recommended as I have a query that joins multiple tables and would be very slow. Is there any other solution?
Thanks
I take that back looks like you can use the cursor orientation contants to select the result... sample code coming... I havent tried this so you may need to play a bit. This is also based on the assumption that a PDO::FETCH_ORI_FIRST acts like a data_seek and leaves the cursor on the first position as opposed to returning it to whatever it was before.
$stmt = $pdo->prepare('SELECT id FROM table', array(PDO::ATTR_CURSOR => PDO::CURSOR_SCROLL));
$stmt->execute();
$first = $pdo->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_FIRST);
$first_row = $first['id'];
// other stuff
// first iteration we rewind to the first record;
$cursor = PDO::FETCH_ORI_FIRST;
while (false !== ($row = $stmt->fetch(PDO::FETCH_ASSOC, $cursor))) {
$id = $row['id'];
// successive iterations we hit the "next" record
$cursor = PDO::FETCH_ORI_NEXT;
echo $id;
}
I dont think you can rewind a statement... Assuming these blocks arent seprated by a bunch of intermediary logic id just do it in the loop.
$STH->setFetchMode(PDO::FETCH_COLUMN); // no need to pull an array
$count = 0;
while ($id = $STH->fetch()) {
if($count === 0) {
$first_row = $id;
}
echo $id;
$count++;
}
Could you just use a do...while loop instead?
$STH->setFetchMode(PDO::FETCH_ASSOC);
$list = $STH->fetch();
$first_id = $list['id'];
do {
$id = $list['id'];
echo $id;
} while ($list = $STH->fetch());
You can fetch all the result, and then just act on it as an array. So, for instance, you could shift the first result off the front, and then loop over any additional rows:
<?php
$sql = "YOUR QUERY";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
// get first row
$firstRow = array_shift($rows);
// loop over remaining rows
foreach ($rows as $row) {
// do something
}

Return a multidimensional array from MySQL result php

I have a PHP function that extract dat of an invoice from DB.
The invoice may have more then one line (one product).
function getInvoiceLines($id)
{
$res = mysql_query("select * from invoice_lines where id = $id ");
while ($row = mysql_fetch_array($res))
{
$res_retun['ref']=$row['ref'];
$res_retun['label']=$row['label'];
$res_retun['price']=$row['label'];
$res_retun['qty']=$row['qty'];
}
return $res_retun ;
}
I found this link Create a Multidimensional Array with PHP and MySQL and I made this code using that concept.
Now, how can I move something like a cursor to the next line and add more lines if there's more in MySQL result??
If it's possible, how can I do to show data in HTML with for ??
A little modification should get what you want, below the [] operator is a shorthand notation to add elements to an array, the problem with your code is that you are overwriting the same keys on each iteration
// fetch only what you need;
$res = mysql_query("select ref, label, price, qty from invoice_lines where id = $id ");
while ($row = mysql_fetch_array($res))
{
$res_return[] = $row;
}
return $res_return;
Note, I fixed some of your typos (you were using $rw instead of $row in the loop of your original code)
If you used PDO with fetchAll() you would be returned with the array your expecting, also be safe from nastys:
<?php //Cut down
$db = new PDO("mysql:host=localhost;dbname=dbName", 'root', 'pass');
$sql = "SELECT * FROM invoice_lines WHERE id = :id ";
$stmt = $db->prepare($sql);
$stmt->bindParam(':id', $id);
$stmt->execute();
$res_return = $stmt->fetchAll(PDO::FETCH_ASSOC);
?>
Then you just loop through the array like with any other array:
<?php
foreach($res_return as $row){
echo $row['ref'];
...
...
}
?>
Also id should not have more then 1 row it should be unique IF its your primary key.
If you were using PDO like you should be it would be super easy and you would solve your sql injection issues
$db = new PDO(...);
function getInvoiceLines( $db, $id )
{
$stmnt = $db->prepare("select ref, label, price, qty from invoice_lines where id=?");
$stmnt->execute( array( $id ) );
return $stmnt->fetchAll( PDO::FETCH_ASSOC );
}
Make variable global first Then access it in function. For exp.
$return_arr = array(); // outside function
$i = 0;
cal_recursive(); // call function first time
function cal_recursive(){
global $return_arr;
global $i;
$return_arr[$i] = // here push value to array variable
$i++;
// do code for recursive function
return $return_arr // after end
}

PHP PDO FetchAll arguments to remove row number from results

I am building a function that acts like Drupal's variable_initialize() function that pulls all key/value pairs into a global variable. I am trying to find the proper parameters I need to put into fetchAll() to remove the row number and get basically what fetch(PDO::FETCH_ASSOC) does but for all returned rows.
I basically want fetchAll to return:
Array {
[name] = value,
[name2] = value2,
[name3] = value3,
}
The variable table is a simple 2 column table (name)|(value)
function variable_init() {
global $db, $variable;
$query = "SELECT * FROM variable";
$stmt = $db->prepare($query);
$stmt->execute();
$result = $stmt->fetchAll(); //need help here
foreach($result as $name => $value) {
$variable[$name] = $value;
}
}
I have tried PDO_COLUMN/PDO_GROUP/etc... but I can't seem to offset the array to remove the row numbers. Thanks.
I think you may be getting confused about what PDOStatement::fetchAll() returns.
The method returns all rows (arrays or objects, depending on fetch style) in an array.
Try this
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($result as $row) {
$variable[$row['name']] = $row['value'];
}

Categories