Mysqli query with bind params using fetch_array - php

I know how to use fetch_array instead of printf() function when expressing rows from database using mysqli bind function.
How can I use $row->mysqli_fetch_array and then use $row[0],$row[1] instead of using the printf() function every time I want to print something from database?

Returning an associative array from a prepared statement you can follow up the procedure like this as follows.
<?php
$category = $_POST['category'];
$sql = "select id, name from items where category = ?";
$stmt = $connection->prepare($sql);
$stmt->bind_param('s', $category);
if($stmt->execute())
{
$result = $stmt->get_result();
$a = $result->fetch_array(MYSQLI_ASSOC); // this does work :)
}
else
{
error_log ("Didn't work");
}
?>
You can use while loop for printing up the value over from the associative array.
while($a = $result->fetch_array(MYSQLI_ASSOC))
{
echo 'Id: '. $a['id'];
echo '<br>';
echo 'Name: '.$a['name'];
}
Output:
Id: 1
Name: Example

If I got your question correctly you can try:
$row=mysqli_fetch_array($result,MYSQLI_NUM);
foreach($row as $cell) {
echo "$cell";
}

Related

Prepared Statement, Fails when re-used

I have this code, works fine when looped through once.
<!-- language: php -->
<?php
$query = "SELECT username FROM users WHERE user_id = ? LIMIT 1";
$stmt = $con->prepare($query) or die(mysqli_error($con));
$stmt->bind_param("s", $user_id);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($username);
?>
When I call it for the first time on the page, it loads fine and the data shows as it should.
<!-- language: php -->
<?php
// This one works fine.
while ($stmt->fetch()){
echo 'Welcome '.$username;
}
?>
If I want to re-use the same query somewhere else, it fails wihtout errors. Am I doing it wrong? What is the correct way to re-use the same query multiple time on the same page, Since the data is the same, I don't want to re-query the DB each time.
<!-- language: php -->
<?php
// When re-used somewhere else on the page, it fails. Nothing shows.
while ($stmt->fetch()){
echo 'Welcome '.$username;
}
?>
fetch returns one row after another. Once you fetch all rows, any further call to fetch() method will return false.
You need to re-execute() the query in order to get the same result again. This will go to call database again though. If you want to cache the result, you need to put it into some in-memory cache / global variable / whatever you prefer.
If you really want to get to the beginning of result set again, you can use mysqli_data_seek() for this:
mysqli_data_seek($stmt, 0);
while ($stmt->fetch()){
echo 'Welcome '.$username;
}
You could pull the query result into an array with fetchAll
$users = $stmt->fetchAll();
// this works
foreach($users as $user) {
echo 'Welcome ' . $username;
}
// this works again
foreach($users as $user) {
echo 'Welcome ' . $username;
}
More information here: http://php.net/manual/fr/pdostatement.fetchall.php
What you can do is get the result-set as an ASSOC Array and save the result in a variable. Now you can use this array as many times as you want.
Update your code like this,
$stmt->setFetchMode(PDO::FETCH_ASSOC);
$results = $stmt->fetchAll();
foreach ($results as $r) {
//first time use
}
foreach ($results as $r) {
//second time use
}
I needed to split up the code to achieve what I needed with MySQL(i).
Thanks for your inputs.
<?php
// Preparing the statement
$query = "SELECT username FROM users WHERE user_id = ? LIMIT 1";
$stmt = $con->prepare($query) or die(mysqli_error($con));
$stmt->bind_param("s", $user_id);
$stmt->store_result();
?>
<?php
// Executing it when needed and creating some variables for later re-use
$stmt->execute();
$stmt->bind_result($username);
while ($stmt->fetch()) {
$new_username = $username;
echo 'Welcome '.$new_username;
}
?>
<?php
// It is possible now to re-use the same result set
echo 'Welcome '.$new_username;
?>
You can store the results:
<?
$query = "SELECT username FROM users WHERE user_id = ? LIMIT 1";
$stmt = $con->prepare($query) or die(mysqli_error($con));
$stmt->bind_param("s", $user_id);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($col['username']);
$result = array();
for ($i = 0; $i < $stmt->num_rows; $i++){
$stmt->data_seek($i);
$stmt->fetch();
foreach ($col as $key => $value){
$result[$i][$key] = $value;
}
}
?>

Using PDO to return a single set of values rather than an array

A very nice person on this site helped me with the following script (and it worked a treat)
<?php
$db = new PDO('mysql:host=HOST;dbname=DATABASE', $user, $pass);
$stmt = $db->prepare('
SELECT
yeast,
rating,
description,
weblink,
image,
sideimage
FROM dowdb_yeast_selector
WHERE
fruit = :fruit
ORDER BY
rating DESC
');
$stmt->bindParam(':fruit',$_POST['fruit'],PDO::PARAM_STR,50);
$stmt->execute();
How do I just echo side image (not as part of a while loop)?
I think (?) I need something like echo '$row[sideimage]' // how simple am I
All of the examples I have looked at so far do not fit my needs :-(
Use PDO::fetchAll, for example;
$stmt->execute();
$arrResults = $stmt->fetchAll();
//$arrResults will be multidimensional
//This will echo the first sideimage
echo $arrResults[0]['sideimage'];
If you want to echo all values of sideimage (ie: all rows), you'd have to iterate through the results;
foreach($arrResults as $arrRow) {
echo $arrRow['sideimage'] . PHP_EOL;
}
Links
pdo::fetchAll
You should use loop pdo::fetch()
while($abc = $stmt->fetch())
{
print_r($abc);
}
If you don't want to use loop try pdo::fetchAll()
$data = $stm->fetchAll();
You could use FETCH_ASSOC
$res = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo $res[0]['sideimage'];
or
foreach($res as $key=>$value) {
$image_val = $value['sideimage'];
}

Saving PDO-data in array

i am doing this select:
$result = $dbh->query("SELECT clicks FROM table WHERE click_date = '".$current_date."'");
$result->execute();
$array = array();
while ($user = $result->fetch(PDO::FETCH_ASSOC)) {
array_push($array, $user['clicks'].",");
}
But this returns:
49572940
But it should be:
4,9,5,7,2,9,4,0
Anybody could help me to fix this problem?
Greetings!
Try this way:
<?php
$sql = "SELECT clicks FROM table WHERE click_date = '$current_date'";
foreach ($dbh->query($sql) as $row) {
$array[] = $row['clicks'];
}
//now echo and use implode
echo implode(", ", $array);
?>
because according to PHP Manual - PDO::query:
PDO::query — Executes an SQL statement, returning a result set as a
PDOStatement object
You should use fetchAll to get all the values and also if you want to execute a prepared statement you have to use prepare instead of query.
$sth = $dbh->prepare("SELECT clicks FROM table WHERE click_date = :current_date");
$sth->bindParam(':current_date', $current_date);
$sth->execute();
$result = $sth->fetchAll();
and after if you want a string with values separate by comma you can use implode as #jason suggested.
$str = implode(",", $result );

How to use bind_result() instead of get_result() in php

I'm working on a project for uni and have been using the following code on a testing server to get all devices from a table based on a user_id:
public function getAllDevices($user_id) {
$stmt = $this->conn->prepare("SELECT * FROM devices WHERE primary_owner_id = ?");
$stmt->bind_param("i", $user_id);
$stmt->execute();
$devices = $stmt->get_result();
$stmt->close();
return $devices;
}
This worked fine on my testing server but returns this error when migrating over to the university project server:
Call to undefined method mysqli_stmt::get_result()
Some googling suggests using bind_result() instead of get_result() but I have no idea how to do this all fields in the table. Most examples only show returning one field
Any help would be much appreciated
Assuming you can't use get_result() and you want an array of devices, you could do:
public function getAllDevices($user_id) {
$stmt = $this->conn->prepare("SELECT device_id, device_name, device_info FROM devices WHERE primary_owner_id = ?");
$stmt->bind_param("i", $user_id);
$stmt->execute();
$stmt->bind_result($id, $name, $info);
$devices = array();
while($stmt->fetch()) {
$tmp = array();
$tmp["id"] = $id;
$tmp["name"] = $name;
$tmp["info"] = $info;
array_push($devices, $tmp);
}
$stmt->close();
return $devices;
}
This creates a temporary array and stores the data from each row in it, and then pushes it to the main array. As far as I'm aware, you can't use SELECT * in bind_result(). Instead, you will annoyingly have to type out all the fields you want after SELECT
By now, you've certainly grasped the idea of binding to multiple variables. However, do not believe the admonitions about not using "SELECT *" with bind_result(). You can keep your "SELECT *" statements... even on your server requiring you to use bind_result(), but it's a little complicated because you have to use PHP's call_user_func_array() as a way to pass an arbitrary (because of "SELECT *") number of parameters to bind_result(). Others before me have posted a handy function for doing this elsewhere in these forums. I include it here:
// Take a statement and bind its fields to an assoc array in PHP with the same fieldnames
function stmt_bind_assoc (&$stmt, &$bound_assoc) {
$metadata = $stmt->result_metadata();
$fields = array();
$bound_assoc = array();
$fields[] = $stmt;
while($field = $metadata->fetch_field()) {
$fields[] = &$bound_assoc[$field->name];
}
call_user_func_array("mysqli_stmt_bind_result", $fields);
}
Now, to use this, we do something like:
function fetch_my_data() {
$stmt = $conn->prepare("SELECT * FROM my_data_table");
$stmt->execute();
$result = array();
stmt_bind_assoc($stmt, $row);
while ($stmt->fetch()) {
$result[] = array_copy($row);
}
return $result;
}
Now, fetch_my_data() will return an array of associative-arrays... all set to encode to JSON or whatever.
It's kinda crafty what is going on, here. stmt_bind_assoc() constructs an empty associative array at the reference you pass to it ($bound_assoc). It uses result_metadata() and fetch_field() to get a list of the returned fields and (with that single statement in the while loop) creates an element in $bound_assoc with that fieldname and appends a reference to it in the $fields array. The $fields array is then passed to mysqli_stmt_bind_result. The really slick part is that no actual values have been passed into $bound_assoc, yet. All of the fetching of the data from the query happens in fetch_my_data(), as you can see from the fact that stmt_bind_assoc() is called before the while($stmt->fetch()).
There is one catch, however: Because the statement has bound to the references in $bound_assoc, they are going to change with every $stmt->fetch(). So, you need to make a deep copy of $row. If you don't, all of the rows in your $result array are going to contain the same thing: the last row returned in your SELECT. So, I'm using a little array_copy() function that I found with the Google:
function array_copy( array $array ) {
$result = array();
foreach( $array as $key => $val ) {
if( is_array( $val ) ) {
$result[$key] = arrayCopy( $val );
} elseif ( is_object( $val ) ) {
$result[$key] = clone $val;
} else {
$result[$key] = $val;
}
}
return $result;
}
Your question suggests that you have MySQL Native driver (MySQLnd) installed on your local server, but MySQLnd is missing on the school project server. Because get_result() requires MySQLnd.
Therefore, if you still want to use get_result() instead of bind_result() on the school project server, then you should install MySQLnd on the school project server.
in order to use bind_result() you can't use queries that SELECT *.
instead, you must select individual column names, then bind the results in the same order. here's an example:
$stmt = $mysqli->prepare("SELECT foo, bar, what, why FROM table_name WHERE id = ?");
$stmt->bind_param("i", $id);
if($stmt->execute()) {
$stmt->bind_result($foo, $bar, $what, $why);
if($stmt->fetch()) {
$stmt->close();
}else{
//error binding result(no rows??)
}
}else{
//error with query
}
get_result() is now only available in PHP by installing the MySQL native driver (mysqlnd). In some environments, it may not be possible or desirable to install mysqlnd.
Notwithstanding, you can still use mysqli to do 'select *' queries, and get the results with the field names - although it is slightly more complicated than using get_result(), and involves using php's call_user_func_array() function. See example below which does a simple 'select *' query, and outputs the results (with the column names) to an HTML table:
$maxaccountid=100;
$sql="select * from accounts where account_id<?";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param('i', $maxaccountid);
$stmt->execute();
print "<table border=1>";
print "<thead><tr>";
$i=0;
$meta = $stmt->result_metadata();
$query_data=array();
while ($field = $meta->fetch_field()) {
print "<th>" . $field->name . "</th>";
$var = $i;
$$var = null;
$query_data[$var] = &$$var;
$i++;
}
print "</tr></thead>";
$r=0;
call_user_func_array(array($stmt,'bind_result'), $query_data);
while ($stmt->fetch()) {
print "<tr>";
for ($i=0; $i<count($query_data); $i++) {
print "<td>" . $query_data[$i] . "</td>";
}
print "</tr>";
$r++;
}
print "</table>";
$stmt->close();
print $r . " Records<BR>";

PHP - function for mysql_fetch_assoc

If I do this in PHP, it works fine and loops as expected:
$rs = mysql_query($sql);
while ($row = mysql_fetch_assoc($rs)){
writeme("UserID: " . $row["UserID"]);
}
But I keep wanting to abstract this out into a function I have called ExecuteQuery:
function ExecuteQuery($sql){
$result = mysql_query($sql);
if ($result) {
if($result != 1){
return mysql_fetch_assoc($result); // return recordset
}
}else{
$message = 'Invalid query: ' . mysql_error() . "<br>";
$message .= 'Whole query: ' . $sql;
echo $message;
die();
}
}
This function works great in 2 out of 3 scenarios:
1- Works great for a query that returns 1 row, and I can access like this:
$rs = ExecuteQuery($sql);
$foo = $rs["UserID"];
2- Works great for a sql statement that returns no records, like an UPDATE or DELETE.
3- But when I try to get back a recordset that returns multiple records, and then loop through it, I get an infinite loop and my browser crashes. Like this:
$rs = ExecuteQuery($sql);
while ($row = $rs){
writeme("UserID: " . $row["UserID"]);
}
How can I modify my while loop so it advances to each new record in the recordset and stops after the last record? I'm sure it's a dumb little thing, but I'm not expert with PHP yet. I'd really like my ExecuteQuery function to be able to handle all 3 scenarios, it's very handy.
try foreach($rs as $row){ instead of while ($row = $rs){
mysql_fetch_assoc() only returns one row of the result. To get the next row, you need to call mysql_fetch_assoc() again. One thing you could do is have your ExecuteQuery function return an array of arrays:
$rows = array();
while ($row = mysql_fetch_assoc($result) !== false) {
$rows[] = $row;
}
return $rows;
Also, you should not use the mysql_* functions as they are deprecated. Try using PDO or mysqli_* instead.
Don't use while, use foreach:
$rs = ExecuteQuery($sql);
foreach ($rs as $row){
writeme("UserID: " . $row["UserID"]);
}

Categories