Trying to transition over my old mysql queries to mysqli prepared statements. I've got everything figured out except for one thing. How can I get the query results stored as an array? I used to do this like this:
$sql = "SELECT * FROM Users";
$result = mysql_query($sql);
while ($row = mysql_fetch_array($result) {
// do stuff
}
Now I have the following code. In this case, my array is a single record, so I don't need to iterate over it, but I want to hold it as an array so that I can refer to its field names. Also, I will have other queries that will return multiple records, so I'll need to iterat then.
$sql = "SELECT * FROM Users
WHERE (LOWER(first_name)=LOWER(?) && LOWER(last_name)=LOWER(?))";
$stmt = mysqli_stmt_init($link);
$this_user;
if (mysqli_stmt_prepare($stmt, $sql)) {
/* Bind the input parameters to the query */
mysqli_stmt_bind_param($stmt, 'ss', $first_name, $last_name);
/* execute query, store results in an array */
mysqli_stmt_execute($stmt);
$result = mysqli_fetch_array($stmt);
if (mysqli_num_rows($result) == 0) {
mysqli_stmt_close($stmt);
mysqli_close($link);
$tag_result = "failure";
$tag_message = "No matching user found";
echo encodeJSONObj($tag_result, $tag_message);
die();
}
if (mysqli_num_rows($result) > 1) {
mysqli_close($link);
$tag_result = "failure";
$tag_message = "Multiple records found for this user.";
echo encodeJSONObj($tag_result, $tag_message);
die();
}
$this_user = mysqli_fetch_array($result);
/* close statement */
mysqli_stmt_close($stmt);
}
$id = $this_user['id'];
$first_name = $this_user['first_name'];
$last_name = $this_user['last_name'];
// and so on...
Can somebody tell me what I am doing wrong? Thanks!
EDIT: With big thanks to Phil, I've modified my code. However, I still seem to be returning 0 rows even though my input parameters should return exactly 1 row. Here is what I have:
$sql = "SELECT id, first_name, last_name, group_id, email, cell
FROM Users
WHERE (first_name=? && last_name=?)";
$stmt = mysqli_stmt_init($link);
if (mysqli_stmt_prepare($stmt, $sql)) {
/* Bind the input parameters to the query */
mysqli_stmt_bind_param($stmt, 'ss', $first_name, $last_name);
/* execute query, bind result, and fetch value */
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $id, $first_name, $last_name, $group_id, $email, $cell);
mysqli_stmt_fetch($stmt);
if (mysqli_stmt_num_rows($stmt) == 0) {
mysqli_stmt_close($stmt);
mysqli_close($link);
echo "No results returned";
die();
}
...
}
This always outputs No results returned when it should find 1 row and skip right past that block. I've been staring at this for a long time, but I just can't see what I am doing wrong.
Your script contains numerous errors (as mentioned in comments above). Here's a simple step-by-step...
Prepare a statement and bind parameters
$stmt = $link->prepare($sql);
if (!$stmt) {
throw new Exception($link->error, $link->errno);
}
// you can error check this too but it rarely goes wrong
$stmt->bind_param('ss', $first_name, $last_name);
Execute the statement and store the result
if (!$stmt->execute()) {
throw new Exception($stmt->error, $stmt->errno);
}
$stmt->store_result();
Do your number of row checks against $stmt->num_rows...
if ($stmt->num_rows == 0) {
// ...
}
if ($stmt->num_rows > 1) {
// ...
}
Bind and fetch the result
// This relies on the SELECT column ordering.
// You should probably change your SELECT statement to
// SELECT id, first_name, last_name FROM Users...
$stmt->bind_result($id, $first_name, $last_name);
$stmt->fetch();
$stmt->close();
$link->close();
If you want to fetch the single result row as an associative array, try this instead
$result = $stmt->get_result(); // note - this requires the mysqlnd driver
$this_user = $result->fetch_array(MYSQLI_ASSOC);
$result->free();
$stmt->close();
$link->close();
Related
Up to now I was checking num_rows >0 the following way:
$sql = "SELECT name FROM tbl_criteria WHERE ID =?";
$stmt = mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt, $sql)){
header("location: /XX");
}else{
mysqli_stmt_bind_param($stmt, "i", $cId);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
mysqli_fetch_all($result,MYSQLI_ASSOC);
if($result-> num_rows >0{
echo 'Appear if rows >0';
foreach($result as $row){
echo 'Appear for each result';
}
}
}
So suddenly this is not working anymore. I always get 0 results. I have read that it is important to call mysqli_stmt_store_result() before accessing num_rows otherwise it would usually return 0. I thought that I'm storing the results with $result = mysqli_stmt_get_result($stmt); or am I wrong?
I am hosting my website on a webserver so it could be because of an update as well. A couple of days ago it was working fine.
Your code is not working most likely due to multiple syntax errors you have. I recommend to read How to get the error message in MySQLi?
If you would like to continue using mysqli, then there is no need for this overly complex code. You can simply fetch all results into an array. There's no need to ever use num_rows.
$value = "cId";
$stmt = $conn->prepare("SELECT name FROM tbl_criteria WHERE ID =?");
$stmt->bind_param('s', $value);
$stmt->execute();
$result = $stmt->get_result()->fetch_all(MYSQLI_ASSOC);
// If no rows were fetched the array will be empty and condition will be false
if ($result) {
echo 'Appear if rows >0';
foreach ($result as $row) {
echo 'Appear for each result';
}
}
Connection is good. I can insert into the database, and check if a row exists by checking if results > 0, but I can not select row data. The $email's being tested are in the database.
Ex 1.
require 'connection/connection.php';
$email = "sample#sample.com";
$sql = "SELECT * FROM users WHERE user_email=?"; // SQL with parameters
$stmt = $conn->prepare($sql);
$stmt->bind_param("s", $email);
$stmt->execute();
$result = $stmt->get_result(); // get the mysqli result
$user = $result->fetch_assoc(); // fetch data
echo $user['user_name'];
Ex. 2
$email = "james#james.com";
$sql = "SELECT * FROM users WHERE user_email=?";
$stmt = mysqli_stmt_init($conn);
mysqli_stmt_bind_param($stmt, "s", $email);
mysqli_stmt_execute($stmt);
After inserting an echo after every line one by one, this is as far as it gets. If an echo statement is placed after the next line it will not appear.
$result = mysqli_stmt_get_result($stmt);
if ($row = mysqli_fetch_assoc($result)) {
$_SESSION['active_user_id'] = $row['user_id'];
} else {
header("Location: https://example.com/");
exit();
}
The problem was fixed through cPanel. I had to switch from "mysqli" to "nd_mysqli." This fixed the problem right away.
I found the instructions to do this here https://www.plus2net.com/php_tutorial/mysqli_mysqlnd.php
I hope this helps others with the same problem.
I am using mysqli to get the row but it is not giving me row, and there is no error in query.
$query="select * from members where useremail='$user_email' and password='$password'";
$result=$db->query($query);
$row = $db->fetch_array($result);
echo $row['id'];
My query Function
function query($query){
$result=mysqli_query($this->conn, $query);
if(!$result){
echo $this->err_msg = mysqli_error($this->conn);
return false;
}else{
return $result;
}
}
My fetch_array Function
function fetch_array($result){
return mysqli_fetch_array($result);
}
How can i get Row using mysqli ?
Change your original code to reflect bound parameters using mysqli, this is more secure and should work
$query="select * from members where useremail='$user_email' and password='$password'";
$result=$db->query($query);
$row = $db->fetch_array($result);
echo $row['id'];
to bound parameters using mysqli prepared statements
$query="select id from members where useremail=? and password=?"; // Don't use select *, select each column, ? are placeholders for your bind variables
$stmt = $connection->prepare($query);
if($stmt){
$stmt->bind_param("ss",$user_email,$password); // Bind in your variables, s is for string, i is for integers
$stmt->execute();
$stmt->bind_result($id); // bind the result to these variables, in the order you select
$stmt->store_result(); // Store if large result set, can throw error if server is setup to not handle more than x data
$stmt->fetch();
$stmt->close();
}
echo $id; // this would be same as $row['id'], $id now holds for example 5.
If you select multiple things, such as "SELECT id,name FROM...", then when you bind_result(..), just bind them n there. $stmt->bind_result($id,$name);
now $id and $name hold the column data for that row matching your query. If there would be multiple rows matching, instead of $stmt->fetch() you'd do
while($stmt->fetch()){ // just like while($row = $result->fetch_assoc()){}
echo $id;
echo $name
}
I have a database in which I have user_id & associated_id.There can be multiple associated_id for a single user_id. Now I want to fetch all the associated_ids into a single array. I have tried this method but don't know how to get them in array.
$stmt = $this->conn->prepare("SELECT * FROM my_contacts WHERE user_id = ?");
$stmt->bind_param("s", $user_id);
if ($stmt->execute())
{
while ($stmt->fetch())
{
//what to write here
}
//echo var_dump($user);
$stmt->close();
}
Try this:
$stmt = $mysqli->prepare("SELECT associated_id FROM my_contacts WHERE user_id = ?")) {
$stmt->bind_param('s', $user_id); // Bind "$user_id" to parameter.
$stmt->execute(); // Execute the prepared query.
$stmt->store_result();
// get variables from result.
$stmt->bind_result($associated_id);
$stmt->fetch();
The results will be stored in the $associated_id array.
You can bind parameters like this and use fetchall method to get all the results in a array
$stmt = $this->conn->prepare("SELECT * FROM my_contacts WHERE user_id = :user_id");
$stmt->bind_param(":user_id", $user_id, PDO::PARAM_INT);
if ($stmt->execute())
{
$result = $stmt->fetchall(PDO::FETCH_ASSOC);
//echo var_dump($user);
$stmt->close();
}
According to your code you used mysqli.
$stmt = $this->conn->prepare("SELECT * FROM my_contacts WHERE user_id = ?");
if($stmt->execute()){
$result = $stmt->get_result();
if($result->nom_rows > 0){
while($row = $result->fetch_assoc()){
var_dump($row)
}
}else{
echo "Sorry NO data found";
}
}else{
echo "Some thing is wrong";
}
here you can't used $stmt->bind_result(); instead of use $stmt->get_result()
$stmt->bind_result(); is only used when you define field in select query
with * you need to used $stmt->get_result()
refer this link for more information
Example of how to use bind_result vs get_result
I'm trying to switch from mySql statements to PDO prepared statements, but I'm having trouble figuring out the correct syntax for the if/else statements that I have to use if the insert was successful (which were previously if($result) {...}).
I know that $stmt->execute(); returns true on success or false on failure, but I haven't been able to determine how to set the statement up to act on that.
The new code (PDO prepared statement)
$gender = $_POST['gender'];
if ($gender==="female" ) {
try {
$stmt = $conn->prepare('INSERT INTO customer_info (fname...) VALUES(:fname...)');
$stmt->bindParam(':fname', $_POST['fname'], PDO::PARAM_STR);
$stmt->execute();
} catch(PDOException $e) {
echo $e->getMessage();
}
This is the rest of the original if ($gender==="female") function
$result = #mysql_query($qry);
if($result) {
$qry="SELECT * FROM customer_info WHERE user_name='$_POST['user_name']' AND password='$_POST['password']'";
$result=mysql_query($qry);
if($result) {
if(mysql_num_rows($result) == 1) {
//user_name Successful
session_regenerate_id();
$member = mysql_fetch_assoc($result);
$_SESSION['SESS_USER_ID'] = $member['user_id'];
session_write_close();
header("location: flatter_iframe.html");
exit();
}else {
header("location: login_failed.html");
exit();
}
I've deleted most of the variables in order to simplify things (since the code is the same)
There are a number of ways you can check whether an INSERT worked correctly.
1. Return value from $stmt->execute()
As you said, $stmt->execute(); returns true on success or false on failure. So you can use:
$result = $stmt->execute();
if ($result) {...}
PDO Execute documentation here
2. Row Count
rowCount will return the number of rows afffected by a query. After a successful insert, this should be 1.
$stmt->execute();
$affected_rows = $stmt->rowCount();
if ($affected_rows == 1) {...}
PDO rowCount documentation here
3. Last Inserted Id
If your table has an ID column, you can return the ID of the last inserted row using lastInsertId().
$stmt->execute();
$newCustomerInfoId = $pdo->lastInsertId();
if ($newCustomerInfoId) {...}
Note: You must call lastInsertId on the PDO object, not the $stmt.
PDO lastInsertId documentation here