runs if statement after else if statement - php

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);
}
?>

Related

MySqli update is taking a while to load/timing out completely after submitting

I'm allowing the logged in user to change the rsvp status via a dropdown on their profile page. When they submit the change, it's taking a while to update the field and sometimes times out. I suspect that I'm causing this with the way it's coded to do the database update but can't figure it out.
<?php
include_once 'header.php';
require_once 'includes/dbh.inc.php';
require_once 'includes/functions.inc.php';
if(isset($_SESSION["emailAddress"])) {
$sql = "SELECT * FROM users WHERE email='$_SESSION[emailAddress]'";
$stmt = mysqli_prepare($conn, $sql);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_assoc($result);
mysqli_stmt_close($stmt);
$inGet = "SELECT * FROM users WHERE rsvp='in';";
$inData = mysqli_query($conn, $inGet);
$inTotal = mysqli_num_rows($inData);
if(isset($_POST['apply'])) {
$rsvp = $_POST['status'];
$email = $_SESSION['emailAddress'];
$firstName = $row['firstName'];
$lastName = $row['lastName'];
do {
$sql2 = "UPDATE users SET rsvp='$rsvp' WHERE email='$_SESSION[emailAddress]';";
$stmt2 = mysqli_prepare($conn, $sql2);
mysqli_stmt_execute($stmt2);
mysqli_stmt_close($stmt2);
} while ($inTotal <= 8);
if (($inTotal == 9 && $rsvp == "in")) {
$sql3 = "UPDATE users SET rsvp='waitlist' WHERE email='$_SESSION[emailAddress]';";
$stmt3 = mysqli_prepare($conn, $sql3);
mysqli_stmt_execute($stmt3);
mysqli_stmt_close($stmt3);
header("Location: dashboard.php");
exit();
}
}
}
?>
I've tried to call and close statements to avoid multiple statements being open at the same time.
I'm expecting the changes to be rather instant in the update of the database to reflect on user's profile and the main dashboard.
This is an infinite loop:
do {
$sql2 = "[your UPDATE statement...]";
$stmt2 = mysqli_prepare($conn, $sql2);
mysqli_stmt_execute($stmt2);
mysqli_stmt_close($stmt2);
} while ($inTotal <= 8);
Because the loop will continue until $inTotal <= 8 is no longer true. But since nothing ever changes $inTotal within the loop, if it's true once then it will always be true.
Taking a step back... Why is this even a loop in the first place? You're just repeatedly executing the same SQL statement. If it succeeds once then it succeeded. Remove the loop and just execute the statement once:
$sql2 = "[your UPDATE statement...]";
$stmt2 = mysqli_prepare($conn, $sql2);
mysqli_stmt_execute($stmt2);
mysqli_stmt_close($stmt2);
Important Note: Notice how I removed the actual UPDATE statement above. That was just to demonstrate the structure of the code after removing the loop. (And to explicitly avoid anybody blindly copying/pasting this answer's content into actual code.) But you will also want to correct a SQL injection vulnerability here (and anywhere else in your code):
$sql2 = "UPDATE users SET rsvp=? WHERE email=?";
$stmt2 = mysqli_prepare($conn, $sql2);
mysqli_stmt_bind_param($stmt2, 'ss', $rsvp, $_SESSION['emailAddress']);
mysqli_stmt_execute($stmt2);
mysqli_stmt_close($stmt2);

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();
}

Prepared statements and mysqli_query / mysqli_num_rows?

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.

MySQLi Prepared Statement Query Results in an Array

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();

Categories