question about mysqli prepared statements - php

I have basic question about mysqli prepared statements. For example, I want to execute a SELECT query, Should I do it like:
<?
$city = "Amersfoort";
if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) {
$stmt->bind_param("s", $city);
$stmt->execute();
$stmt->bind_result($district);
$stmt->close();
}
$mysqli->close();
?>
In the above code, is bind_result also required? What exactly it does?
Also, do I need need to close mysqli connection after each query?
Thanks.

bind_result makes it so that when you iterate over the results of the query, the columns from the result set are automatically mapped to local variables.
For example, suppose you execute a query that returns a result set with three columns like this:
$query = "SELECT Name, CountryCode, District FROM myCity";
You want to execute the query and do something with the results, let's say print them:
if ($result = $mysqli->query($query)) {
while ($row = $result->fetch_row()) {
printf("%s (%s,%s)\n", $row[0], $row[1], $row[2]);
}
}
The "problem" with the above code is that $row[0] is not very descriptive. An alternative way is to use bind_result, which goes like this:
$query = "SELECT Name, CountryCode, District FROM myCity";
if ($stmt = $mysqli->prepare($query)) {
$stmt->bind_result($name, $countryCode, $district);
while ($stmt->fetch()) {
printf("%s (%s,%s)\n", $name, $countryCode, $district);
}
}
As you see, when using bind_result each time you call fetch the variables $name, $countryCode, $district are automatically populated with the values from the current result row. There are some details that you must ensure, read the documentation for more info.
To answer your other question: you do not need to, and indeed you must not close the connection after each query (unless you know very well what you are doing).

bind_result assigns the variable to which data will be written. And you can keep the connection open. Just make sure you call $stmt->fetch() after $stmt->bind_result($district);
Check out Example #1 here:
http://www.php.net/manual/en/mysqli-stmt.bind-result.php

Related

get_result() doesn't work on my web host [duplicate]

I would like to see an example of how to call using bind_result vs. get_result and what would be the purpose of using one over the other.
Also the pro and cons of using each.
What is the limitation of using either and is there a difference.
Although both methods work with * queries, when bind_result() is used, the columns are usually listed explicitly in the query, so one can consult the list when assigning returned values in bind_result(), because the order of variables must strictly match the structure of the returned row.
Example 1 for $query1 using bind_result()
$query1 = 'SELECT id, first_name, last_name, username FROM `table` WHERE id = ?';
$id = 5;
$stmt = $mysqli->prepare($query1);
/*
Binds variables to prepared statement
i corresponding variable has type integer
d corresponding variable has type double
s corresponding variable has type string
b corresponding variable is a blob and will be sent in packets
*/
$stmt->bind_param('i',$id);
/* execute query */
$stmt->execute();
/* Store the result (to get properties) */
$stmt->store_result();
/* Get the number of rows */
$num_of_rows = $stmt->num_rows;
/* Bind the result to variables */
$stmt->bind_result($id, $first_name, $last_name, $username);
while ($stmt->fetch()) {
echo 'ID: '.$id.'<br>';
echo 'First Name: '.$first_name.'<br>';
echo 'Last Name: '.$last_name.'<br>';
echo 'Username: '.$username.'<br><br>';
}
Example 2 for $query2 using get_result()
$query2 = 'SELECT * FROM `table` WHERE id = ?';
$id = 5;
$stmt = $mysqli->prepare($query2);
/*
Binds variables to prepared statement
i corresponding variable has type integer
d corresponding variable has type double
s corresponding variable has type string
b corresponding variable is a blob and will be sent in packets
*/
$stmt->bind_param('i',$id);
/* execute query */
$stmt->execute();
/* Get the result */
$result = $stmt->get_result();
/* Get the number of rows */
$num_of_rows = $result->num_rows;
while ($row = $result->fetch_assoc()) {
echo 'ID: '.$row['id'].'<br>';
echo 'First Name: '.$row['first_name'].'<br>';
echo 'Last Name: '.$row['last_name'].'<br>';
echo 'Username: '.$row['username'].'<br><br>';
}
bind_result()
Pros:
Works with outdated PHP versions
Returns separate variables
Cons:
All variables have to be listed manually
Requires more code to return the row as array
The code must be updated every time when the table structure is changed
get_result()
Pros:
Returns associative/enumerated array or object, automatically filled with data from the returned row
Allows fetch_all() method to return all returned rows at once
Cons:
requires MySQL native driver (mysqlnd)
Examples you can find on the respective manual pages, get_result() and bind_result().
While pros and cons are quite simple:
get_result() is the only sane way to handle results
yet it could be not always available on some outdated and unsupported PHP version
In a modern web application the data is never displayed right off the query. The data has to be collected first and only then output has to be started. Or even if you don't follow the best practices, there are cases when the data has to be returned, not printed right away.
Keeping that in mind let's see how to write a code that returns the selected data as a nested array of associative arrays using both methods.
bind_result()
$query1 = 'SELECT id, first_name, last_name, username FROM `table` WHERE id = ?';
$stmt = $mysqli->prepare($query1);
$stmt->bind_param('s',$id);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($id, $first_name, $last_name, $username);
$rows = [];
while ($stmt->fetch()) {
$rows[] = [
'id' => $id,
'first_name' => $first_name,
'last_name' => $last_name,
'username' => $username,
];
}
and remember to edit this code every time a column is added or removed from the table.
get_result()
$query2 = 'SELECT * FROM `table` WHERE id = ?';
$stmt = $mysqli->prepare($query2);
$stmt->bind_param('s', $id);
$stmt->execute();
$rows = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
and this code remains the same when the table structure is changed.
And there's more.
In case you decide to automate the boring routine of preparing/binding/executing into a neat function that would be called like this
$query = 'SELECT * FROM `table` WHERE id = ?';
$rows = prepared_select($query, [$id])->fetch_all(MYSQLI_ASSOC);
with get_result() it will be quite a plausible task, a matter of just a few lines. But with bind_param() it will will be a tedious quest.
That's why I call the bind_result() method "ugly".
get_result() is 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 at How to use bind_result() instead of get_result() in php which does a simple SELECT * query and outputs the results (with the column names) to an HTML table.
Main difference I've noticed is that bind_result() gives you error 2014, when you try to code nested $stmt inside other $stmt, that is being fetched (without mysqli::store_result() ):
Prepare failed: (2014) Commands out of sync; you can't run this command now
Example:
Function used in main code.
function GetUserName($id)
{
global $conn;
$sql = "SELECT name FROM users WHERE id = ?";
if ($stmt = $conn->prepare($sql)) {
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->bind_result($name);
while ($stmt->fetch()) {
return $name;
}
$stmt->close();
} else {
echo "Prepare failed: (" . $conn->errno . ") " . $conn->error;
}
}
Main code.
$sql = "SELECT from_id, to_id, content
FROM `direct_message`
WHERE `to_id` = ?";
if ($stmt = $conn->prepare($sql)) {
$stmt->bind_param('i', $myID);
/* execute statement */
$stmt->execute();
/* bind result variables */
$stmt->bind_result($from, $to, $text);
/* fetch values */
while ($stmt->fetch()) {
echo "<li>";
echo "<p>Message from: ".GetUserName($from)."</p>";
echo "<p>Message content: ".$text."</p>";
echo "</li>";
}
/* close statement */
$stmt->close();
} else {
echo "Prepare failed: (" . $conn->errno . ") " . $conn->error;
}

SELECT * FROM and mysqli_fetch_array using Prepared Statements

After a long time avoiding Prepared Statements I want to leave my comfort zone and update all my sites to mysqli, but I'm having a really hard time to achieve things that seem simple before...
Connection
$conn = mysqli_connect($host, $user, $password, $database)or die(mysqli_error($conn));
All my query's were built this way:
$id = 1;
$result = mysqli_query($conn, "SELECT * FROM users WHERE id = '$id'");
$row = mysqli_fetch_array($result);
Then I could print all needed fields:
Name: $row['name'];
Email: $row['email'];
Address: $row['address'];
City: $row['city'];
...
I've tried several ways to prepare, execute, bind and fetch the results in a simple way, or similar to what I was used to, but none of them work for me.
My statement is that bad? I mean, if I sanitize all itens before any Query or Insert my statement will remain insecure?
Can anyone show me a example of how can I use prepared statement but still be able to print my results individually, like: $row['name], $row['address'], $row['city']...
JUST TO UPDATE A FEW THINGS
This code works properly, my connection is ok and the $id is declared above my query (I've edited my question). My question is how can I "transform" this code into a mySQLi Prepared Statement and still be able to print results individually like $row['name'], $row['address']...
<?php
$mysqli = new mysqli("localhost", "username", "password", "db_name");
if (mysqli_connect_errno()) {
printf("Connect failed: %s\n", mysqli_connect_error());
exit();
}
$id =1;
if ($stmt = $mysqli->prepare("SELECT name, email from users where id=?")) {
/* bind parameters for markers */
$stmt->bind_param("d", $id);
/* execute query */
$stmt->execute();
$stmt->bind_result($name, $email);
/* fetch value */
$stmt->fetch();
printf("%s has email %s", $name, $email);
/* close statement */
$stmt->close();
}
?>
May it help

MySQL Query not returning a row value in PHP

I don't know why this query won't return a value because when I copy the "echoed" portion into phpmyadmin I do get a record returning:
echo $_GET["cname"];
// Query template
$sql = 'SELECT C.cid FROM `Contact` C WHERE C.email="'.$_GET["cname"].'"';
echo $sql;
// Prepare statement
$stmt = $conn->prepare($sql);
$stmt->execute();
$stmt->bind_result( $res_cid);
echo $res_cid;
$res_cid is apparently 0, but I don't know why because when I paste that query manually into phpmyadmin I do get a value... So why doesn't it return anything?
As already mentioned in the comments - you should make sure your code is secured. You better use the bindparam for that.
As for your question - after you execute your query and bind_result you should also fetch to get the actual value from the database, based on your query:
// Prepare statement
$stmt = $conn->prepare($sql);
$stmt->execute();
$stmt->bind_result( $res_cid);
// Fetch to get the actual result
$stmt->fetch();
echo $res_cid;

MySQLi Prepared SELECT Statement not returning proper value? [duplicate]

I would like to see an example of how to call using bind_result vs. get_result and what would be the purpose of using one over the other.
Also the pro and cons of using each.
What is the limitation of using either and is there a difference.
Although both methods work with * queries, when bind_result() is used, the columns are usually listed explicitly in the query, so one can consult the list when assigning returned values in bind_result(), because the order of variables must strictly match the structure of the returned row.
Example 1 for $query1 using bind_result()
$query1 = 'SELECT id, first_name, last_name, username FROM `table` WHERE id = ?';
$id = 5;
$stmt = $mysqli->prepare($query1);
/*
Binds variables to prepared statement
i corresponding variable has type integer
d corresponding variable has type double
s corresponding variable has type string
b corresponding variable is a blob and will be sent in packets
*/
$stmt->bind_param('i',$id);
/* execute query */
$stmt->execute();
/* Store the result (to get properties) */
$stmt->store_result();
/* Get the number of rows */
$num_of_rows = $stmt->num_rows;
/* Bind the result to variables */
$stmt->bind_result($id, $first_name, $last_name, $username);
while ($stmt->fetch()) {
echo 'ID: '.$id.'<br>';
echo 'First Name: '.$first_name.'<br>';
echo 'Last Name: '.$last_name.'<br>';
echo 'Username: '.$username.'<br><br>';
}
Example 2 for $query2 using get_result()
$query2 = 'SELECT * FROM `table` WHERE id = ?';
$id = 5;
$stmt = $mysqli->prepare($query2);
/*
Binds variables to prepared statement
i corresponding variable has type integer
d corresponding variable has type double
s corresponding variable has type string
b corresponding variable is a blob and will be sent in packets
*/
$stmt->bind_param('i',$id);
/* execute query */
$stmt->execute();
/* Get the result */
$result = $stmt->get_result();
/* Get the number of rows */
$num_of_rows = $result->num_rows;
while ($row = $result->fetch_assoc()) {
echo 'ID: '.$row['id'].'<br>';
echo 'First Name: '.$row['first_name'].'<br>';
echo 'Last Name: '.$row['last_name'].'<br>';
echo 'Username: '.$row['username'].'<br><br>';
}
bind_result()
Pros:
Works with outdated PHP versions
Returns separate variables
Cons:
All variables have to be listed manually
Requires more code to return the row as array
The code must be updated every time when the table structure is changed
get_result()
Pros:
Returns associative/enumerated array or object, automatically filled with data from the returned row
Allows fetch_all() method to return all returned rows at once
Cons:
requires MySQL native driver (mysqlnd)
Examples you can find on the respective manual pages, get_result() and bind_result().
While pros and cons are quite simple:
get_result() is the only sane way to handle results
yet it could be not always available on some outdated and unsupported PHP version
In a modern web application the data is never displayed right off the query. The data has to be collected first and only then output has to be started. Or even if you don't follow the best practices, there are cases when the data has to be returned, not printed right away.
Keeping that in mind let's see how to write a code that returns the selected data as a nested array of associative arrays using both methods.
bind_result()
$query1 = 'SELECT id, first_name, last_name, username FROM `table` WHERE id = ?';
$stmt = $mysqli->prepare($query1);
$stmt->bind_param('s',$id);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($id, $first_name, $last_name, $username);
$rows = [];
while ($stmt->fetch()) {
$rows[] = [
'id' => $id,
'first_name' => $first_name,
'last_name' => $last_name,
'username' => $username,
];
}
and remember to edit this code every time a column is added or removed from the table.
get_result()
$query2 = 'SELECT * FROM `table` WHERE id = ?';
$stmt = $mysqli->prepare($query2);
$stmt->bind_param('s', $id);
$stmt->execute();
$rows = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
and this code remains the same when the table structure is changed.
And there's more.
In case you decide to automate the boring routine of preparing/binding/executing into a neat function that would be called like this
$query = 'SELECT * FROM `table` WHERE id = ?';
$rows = prepared_select($query, [$id])->fetch_all(MYSQLI_ASSOC);
with get_result() it will be quite a plausible task, a matter of just a few lines. But with bind_param() it will will be a tedious quest.
That's why I call the bind_result() method "ugly".
get_result() is 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 at How to use bind_result() instead of get_result() in php which does a simple SELECT * query and outputs the results (with the column names) to an HTML table.
Main difference I've noticed is that bind_result() gives you error 2014, when you try to code nested $stmt inside other $stmt, that is being fetched (without mysqli::store_result() ):
Prepare failed: (2014) Commands out of sync; you can't run this command now
Example:
Function used in main code.
function GetUserName($id)
{
global $conn;
$sql = "SELECT name FROM users WHERE id = ?";
if ($stmt = $conn->prepare($sql)) {
$stmt->bind_param('i', $id);
$stmt->execute();
$stmt->bind_result($name);
while ($stmt->fetch()) {
return $name;
}
$stmt->close();
} else {
echo "Prepare failed: (" . $conn->errno . ") " . $conn->error;
}
}
Main code.
$sql = "SELECT from_id, to_id, content
FROM `direct_message`
WHERE `to_id` = ?";
if ($stmt = $conn->prepare($sql)) {
$stmt->bind_param('i', $myID);
/* execute statement */
$stmt->execute();
/* bind result variables */
$stmt->bind_result($from, $to, $text);
/* fetch values */
while ($stmt->fetch()) {
echo "<li>";
echo "<p>Message from: ".GetUserName($from)."</p>";
echo "<p>Message content: ".$text."</p>";
echo "</li>";
}
/* close statement */
$stmt->close();
} else {
echo "Prepare failed: (" . $conn->errno . ") " . $conn->error;
}

Understanding PHP Prepared Statements

I have a website, and the user has just logged in and it redirects them to the User Dashboard. I have the user_id in a SESSION so I can use that for my SELECT queries to grab other information about the user.
My question is, how can I use Prepared Statments to just grab the variables that I need for that page, without using a foreach statement or a while statement. It will just be for that specific user logged in, not displaying information for multiple users.
Every example I look up is like this:
$query = "SELECT Name, CountryCode FROM City ORDER by ID DESC LIMIT 150,5";
if ($stmt = $mysqli->prepare($query)) {
/* execute statement */
$stmt->execute();
/* bind result variables */
$stmt->bind_result($name, $code);
/* fetch values */
while ($stmt->fetch()) {
printf ("%s (%s)\n", $name, $code);
}
/* close statement */
$stmt->close();
}
/* close connection */
$mysqli->close();
Does it have to be in a while statement? I just need the variables at the top, so I can display my regular page and then use the variables when I need to. Does that make sense?
Just looking to learn more and get a better understanding of how this works.
If you just need the top record:
/* fetch values */
$stmt->fetch();
printf ("%s (%s)\n", $name, $code);
$stmt->fetch will fetch the first row, you don't need the while unless you want to continue through all the rows.

Categories