Prepared statements and mysqli_query / mysqli_num_rows? - php

I am trying to find out how to make my code work with prepared statements. I understood the entire process up to where I commented my code. What do I have to do in order to integrate num_rows and the mysqli_query part properly?
function login_check() {
global $connection;
$name = $_POST['name'];
$password = $_POST['password'];
$query = "SELECT id FROM members WHERE name = $name AND password = $password";
$stmt = $connection->prepare($query);
$stmt->bind_param('ss', $name, $password);
$stmt->execute();
$stmt->close();
// $result = mysqli_query($connection, $query);
// $rows = mysqli_num_rows($result);
if($rows > 0){
header('location:../../success.php');
exit;
}
else {
header('location:../../failed.php');
exit;
}
}
What I tried:
$result = mysqli_query($connection, $stmt);
$rows = mysqli_num_rows($result);

Change
$query = "SELECT id FROM members WHERE name = $name AND password = $password";
to
$query = "SELECT `id` FROM `members` WHERE `name` = ? AND `password` = ?";
Adding backticks around table and columns prevents mysql reserved words error.
Remove $stmt->close();
if( $stmt->num_rows > 0 ) {
$stmt->close();
header('location:../../success.php');
exit();
} else {
$stmt->close();
header('location:../../failed.php');
exit();
}
Adding $stmt->close() inside if statement before header is best practice in this case.
Becasue adding it before if statement would result in $stmt->num_rows always returning 0; Adding it after the if statment won't work because exit() would prefent it from executing.
From the documentation:
Closes a prepared statement. mysqli_stmt_close() also deallocates the statement handle. If the current statement has pending or unread results, this function cancels them so that the next query can be executed.

Related

Why can't I get data from SQL row using PHP prepared statements?

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.

Prepared statement fetch row returns nothing

I want to fetch this row and save it into $notescheck, but when I try to do this the $notescheck is empty when I want to echo and there are no errors. With non-prepared statements it works fine.
Code:
if($user_ok == true) {
$sql = "SELECT notescheck FROM users WHERE username=? LIMIT 1";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s",$log_username);
$stmt->execute();
$row = $stmt->fetch();
$notescheck = $row[0];
$stmt->close();
}
With non-prepared statement it would look like this:
if($user_ok == true) {
$sql = "SELECT notescheck FROM users WHERE username='$log_username' LIMIT 1";
$query = mysqli_query($conn, $sql);
$row = mysqli_fetch_row($query);
$notescheck = $row[0];
mysqli_close($conn);
}
This isn't how fetch() works with prepared statements, you're not fetching an array like you think you are. You also need to bind the result of the select into variables, then use those to display. If there are multiple records, you'd use a while($stmt->fetch){ echo $notescheck };
if($user_ok == true) {
$sql = "SELECT notescheck FROM users WHERE username=? LIMIT 1";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s",$log_username);
$stmt->execute();
$stmt->bind_result($notescheck);
$stmt->fetch();
$stmt->close();
}
echo $notescheck;
You should check into reading this:
http://php.net/manual/en/mysqli-stmt.fetch.php
Multiple records matching username=x would look like this:
if($user_ok == true) {
$sql = "SELECT notescheck FROM users WHERE username=? LIMIT 1";
$stmt = $conn->prepare($sql);
$stmt->bind_param("s",$log_username);
$stmt->execute();
$stmt->bind_result($notescheck);
$stmt->store_result()
while($stmt->fetch()){
echo $notescheck;
}
$stmt->close();
}

runs if statement after else if statement

My code firstly executes the "else if" statement because the "if" statement is not valid. But after it's done executing the "else if" statement it goes into the if statement which now is valid. How can I make it execute only one statement per turn? I mean the whole point with "if" and "elseif" statements is to initially choose the statement that is valid and stop running the code once that statement is executed.
<?php
//mysql_query("SET NAMES utf8");
$con=mysqli_connect("mysql_host","mysql_user","mysql_password","mysql_database");
$email = $_POST["email"];
$query = mysqli_query($con, "SELECT * FROM table WHERE email='{$email}'");
if(mysqli_num_rows($query) >0){
$totalt2 = array();
$totalt2[one] = 'already_exists';
$totalt2[two] = 'already_exists';
$encodedArray2 = array_map(utf8_encode, $totalt2);
echo json_encode($encodedArray2);
mysqli_close($con);
} else if(mysqli_num_rows($query) <1){
$statement = mysqli_prepare($con, "INSERT INTO table (email) VALUES (?) ");
mysqli_stmt_bind_param($statement, "s", $email);
mysqli_stmt_execute($statement);
mysqli_stmt_close($statement);
$totalt = array();
$totalt[one] = 'newly_created';
$totalt[two] = 'newly_created';
$encodedArray = array_map(utf8_encode, $totalt);
echo json_encode($encodedArray);
mysqli_close($con);
}
?>

WHERE statement inside if condition in SQL

Can I do a WHERE clause inside an IF statement?
Like I want something like this:
$SQL = mysql_query("SELECT * FROM `table` ORDER BY `row` DESC");
$rows = mysql_fetch_array($SQL);
$email = $_SESSION['email_of_user'];
if($rows["row"] == "1" WHERE `row`='$email' : ?> (Pulls the logged in user's email)
Edit Server
<?php else : ?>
Add Server
<?php endif; ?>
Do I need (" where the WHERE statement is? Because I tried that and it didn't seem to work...
Or can I do it with an if condition inside of a where clause? Not sure of all these terms yet so correct me if I'm wrong...
You cannot mix up a query statement with PHP's statement. Instead write a query extracting desired results and check if there are any rows from that query.
I will show you an example:
$query = "SELECT * FROM `TABLE_NAME` WHERE `field` = '1' && `email`='$email'"; //Create similar query
$result = mysqli_query($query, $link); //Query the server
if(mysqli_num_rows($result)) { //Check if there are rows
$authenticated = true; //if there is, set a boolean variable to denote the authentication
}
//Then do what you want
if($authenticated) {
echo "Edit Server";
} else {
echo "Add Server";
}
Since Aaron has shown such a effort to encourage safe code in my example. Here is how you can do this securely. PDO Library provides options to bind params to the query statement in the safe way. So, here is how to do it.
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass); //Create the connection
//Create the Query Statemetn
$sth = $dbh->prepare('SELECT * FROM `TABLE_NAME` WHERE field = :field AND email = :email');
//Binds Parameters in the safe way
$sth -> bindParam(':field', 1, PDO::PARAM_INT);
$sth -> bindParam(':email', $email, PDO::PARAM_STRING);
//Then Execute the statement
$sth->execute();
$result = $sth->fetchAll(); //This returns the result set as an associative array

PHP PDO how do i include fetch assoc and numrows

trying to convert all my old mysql_* operations into new and, from what i've heard, improved PDO, but this query wont seem to run successfully, I am trying to select all from the table PEOPLE where the username = $username (which has previously been declared $username = $_SESSION['username'];)
$query = "SELECT * FROM people WHERE username=?";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $username);
$stmt->execute();
$num_rows = $stmt->fetchColumn();
if ($num_rows == 1) {
// ...
}
THE WORKING CODE IS:
$query = "SELECT * FROM people
WHERE username=?";
$stmt = $conn->prepare($query);
$stmt->bindParam(1, $username);
$stmt->execute();
$num_rows = $stmt->fetchColumn();
$user = $stmt->fetchObject();
if ($user) {
//do something
}
$stmt->fetchColumn does not fetch the number of rows; in this case it will fetch the first column from the first row of the result set. Since that will not be equal to 1 generally your test will fail.
In this case there is also no real need to count the number of returned rows because you are expecting either one or zero (if the username does not exist). So you can simply do:
$stmt->execute();
$user = $stmt->fetchObject();
if (!$user) {
// not found
}
else {
echo "User $user->username found!";
}
The if(!$user) test works because if there is no row to fetch $user will be false (see the documentation for fetchObject).
$query = "SELECT * FROM people WHERE username = :username";
$stmt = $conn->prepare($query);
$stmt->bindParam(':username', $username);
$stmt->execute();
while ($row = $stmt->fetchObject()) {
// do stuff
}
Use PDOStatement::rowCount as the num_rows and PDOStatement::fetch(PDO::FETCH_ASSOC) as fetch_assoc equivalent.
You want
if ($stmt->num_rows == 1) {
instead.

Categories