mysqli_stmt_num_rows, mysqli_stmt_execute and mysqli_store_result - php

I have the following function which is supposed to check if a new email address to be added into the database is already in there.
function duplicate_email($email_y){
$dbCon = db_connect();
$sql = "SELECT email FROM users WHERE email = ?";
if ($stmt = mysqli_prepare($dbCon, $sql)) {
mysqli_stmt_bind_param($stmt, "s", $email_y);
mysqli_stmt_execute($stmt);
//mysqli_store_result($dbCon);
$rows = mysqli_stmt_num_rows($stmt);
if($rows == 1){
mysqli_stmt_close($stmt);
mysqli_close($dbCon);
return true;
}
else{
mysqli_stmt_close($stmt);
mysqli_close($dbCon);
return false;
}
}
}
This is where I use it:
if(duplicate_email($email) == true){
echo 'Email [ '.$email.' ] seems to be already used';
}
The problem is that is does not detect, I've tested on an email address that is in the database and it fails, it passes over like its not there.
Any thoughts where it fails?
thx

This might not answer your question, but defensive programming style would recommend that you change your statement to if ($rows >= 1) just in case your test email address is included in your database multiple times.
Also, you should handle the case of your if ($stmt = mysqli_prepare...) not returning true. It'll just fall through to the rest of your code and return nothing, which I believe might be interpreted as false. At the very least, print out some debug code (or raise an exception) if that fails.

Related

Why am I receiving null as a response for an sql column with data in it? (PHP)

I am building a log in system and every other part works perfectly fine except for the portion that cross references the entered password with the password in the database. So when I checked to see if the passwords match I realized that the password from the database is coming back as null. May I ask what is happening?? (There is no issue with the "uidExists" method, it seems to just be in the "loginUser" method).
This is based of of this video https://www.youtube.com/watch?v=gCo6JqGMi30
I believe its around the hour and 40 minute mark he gets to the loginUser function.
function loginUser($conn,$username,$pwd){
$uidExists = uidExists($conn,$username,$username);
if($uidExists === false){
header("location: ../login.php?error=wrongslogin");
exit();
}
else{
echo $pwd;
if(is_null($uidExists["userPwd"])){
echo "Empty bruv";
}
else{
echo $uidExists["userPwd"];
}
}
function uidExists($conn,$username,$email){
$sql = "SELECT * FROM users WHERE userUid = ? OR userEmail = ?;";
$stmt = mysqli_stmt_init($conn);
if(!mysqli_stmt_prepare($stmt,$sql)){
header("location: ../signup.php?error=stmtfailed");
exit();
}
mysqli_stmt_bind_param($stmt,"ss",$username,$email);
mysqli_stmt_execute($stmt);
$resultData = mysqli_stmt_get_result($stmt);
if(mysqli_fetch_assoc($resultData)){
return $row;
}
else{
$result = false;
return $result;
}
mysqli_stmt_close($stmt);
}
This doesn't look right:
$uidExists = uidExists($conn,$username,$username);
Should this be:
$uidExists = uidExists($conn,$username,$userPwd);

I can't seem to get this else statement to work in php

<?php
session_start();
$link = mysqli_connect(database connection info);
if (mysqli_connect_error()) {
echo "Could not connect to database";
die;
}
if (isset($_POST['submit'])) {
$query = "SELECT * FROM users WHERE email = '".$_POST['email']."'";
$result = mysqli_query($link, $query);
if ($row = mysqli_fetch_array($result)) {
if ($_POST['email'] == $row['email'] && password_verify($_POST['password'], $row['password']))
{
$success .= "We're in baby";
} else {
$error .= "didn't work boi";
}
}
}
?>
Basically for some reason the else statement in this code
if ($_POST['email'] == $row['email'] && password_verify($_POST['password'], $row['password']))
{
$success .= "We're in baby";
} else {
$error .= "send help";
}
is not working at all. The problem isn't within the error variable as echo does not work either. I can't get the else statement to output any response whatsoever if the original if statement returns false. The if statement executes perfectly fine if it returns true!
Please help.
As per my comment, to get the else statement executed, enter a valid email address from your database and a wrong password. That should get to the else statement.
To echo $error, define $error = ''; at the top of the script and then add
echo $error; //Below the closing `}` of the `if($row....) ` statement
Also your query is not safe at all. You're directly injecting a variable that can be easily manipulated by anyone. You should never trust such. Hence why we have prepared statements. They help prevent SQL injection attacks as well as those pesky quoting issues. Visit the link below for a tutorial on how to use them with the mysqli_ API.
https://phpdelusions.net/mysqli
Add an else part for the if ($row = mysqli_fetch_array($result)) - perhaps your query fails or the specified email doesn't exist in the db.
The condition $_POST['email'] == $row['email'] is useless as it's already part of the SQL statement.
Also, important(!): your code is vulnerable to SQL injection. Do not put unescaped values from POST to an SQL query.

Ran into an error when creating a Prepared statement to login PHP

I keep running into the error where PHP says "We're sorry we can't log you in." according to one of my conditions set even if login is correct and hence my Prepared system to avoid SQL injection fails.
So my code goes like this:
global $connected;
$post = filter_var_array($_POST, FILTER_SANITIZE_STRING);
$pwwd = $post['password'];
$usrn = $post['username'];
$usrn = mysqli_real_escape_string($connected, $usrn);
$pwwd = mysqli_real_escape_string($connected, $pwwd);
if (strlen($usrn) != 0 && strlen($pwwd) != 0 && !empty($post)) {
$usrn = stripslashes($usrn);
$pwwd = stripslashes($pwwd);
$hashFormat = '$2ysomenumber$';
$salt = 'somehashobviously';
$hashF_and_salt = $hashFormat.$salt;
$pwwd = crypt($pwwd, $hashF_and_salt);
if (!mysqli_connect_errno()) {
mysqli_select_db($connected, 'someDbname') or die('Database select error');
} else {
die('Failed to connect to PHPMyAdmin').mysqli_connect_error();
}
$query = "SELECT Username, Password FROM users WHERE Username=? AND Password=?";
$stmt = mysqli_stmt_init($connected);
if (mysqli_stmt_prepare($stmt, $query)) {
//Some error in here somewhere
mysqli_stmt_bind_param($stmt, "ss", $usrn, $pwwd);
mysqli_stmt_execute($stmt);
mysqli_stmt_fetch($stmt);
mysqli_stmt_bind_result($stmt, $check_usrn, $check_pwd);
if (strcasecmp($usrn, $check_usrn) == 0) {
if ($pwwd == $check_pwd) {
echo '<h1 class="text-center">Matches</h1>';
print_r($row);
}
} else {
echo "<h1 class=text-center>We're sorry we can't log you in.</h1>";
}
}
} else { //This is for strlen boolean cond
echo "<h1 class='text-center'>Both fields must not be empty. </h1>";
}
I used to use a login page without prepared statements which was working, but I realised I need to do this for better security. My database is working fine so the problem is near where I added the comment "//Some error in here somewhere".
I am a relatively new PHP programmer that is yet a first year student trying daring new things in the holidays! Will openly read all the help I get, thank you!
First i didn't see your connection code for connection to the database which is like this.
$connected = msqli_connect(host,user,password,db_name) ; than you don't need to call mysqli_select_db()function.
Secondly you are checking your connectinon from mysqli_connect_errno() function which return 0 as integer (not boolean) if no error code value for last mysqli_connect() function.
Third there is no need to Initializes prepare statement.
Fourth is mysqli_stmt_bind_reslut() comes before the mysqli_stmt_fetch(). see note point in manual
Use hash_equals() function to match password instead of ===. see the warning section in crypt
$connected = msqli_connect(host,user,password,db_name) ;
if(!$connected)
{
die('Connect Error (' . mysqli_connect_errno() . ') '. mysqli_connect_error());
}
echo "Your connection is successful . "
if($stmt = mysqli_prepare($connected,$query))
{
mysqli_stmt_bind_param($stmt, "ss", $usrn, $pwwd);
mysqli_stmt_execute($stmt);
mysqli_stmt_bind_result($stmt, $check_usrn, $check_pwd);
mysqli_stmt_fetch($stmt);
/* Now do Your Work */
} else
{
/* still prepare statement doesn't work */
} `

my select PHP function does not work properly

i create a webservice and i call a function to confirm user, but every time i call the function, i receive "registration confirmed" message even if i send the wrong vercode, here is my function implementation, consider ckey is constant and not changable and vercode is changable for every user, i think the problem is about mysql instructions.
// RPC method 2 (confirm user)
function confuser($ckey, $vercode) {
$db = mysql_connect("localhost","root");
if(!$db){
return 'Error: cannot open the connection';
exit;
}
mysql_select_db('user_info');
$query = "select * from personal where vercode='".$vercode."' and ckey='".$ckey."' ";
$result = mysql_query($query, $db);
if($result){
return 'registration confirmed';
}
else{
return 'wrong verification , send it again!';
}
}
You can use something like this:
if(mysql_num_rows($result) > 0){
return 'registration confirmed';
}
else{
return 'wrong verification , send it again!';
}
mysql_query() will return a result handle on ANY successful query. That includes queries that returned ZERO rows. A zero-row result is still a valid result, it just happens to have nothing in it. You will NOT get a "false" return on zero-row queries.
You need to check the number of rows found, e.g.
$result = mysql_query(...);
if (!$result) {
die(mysql_error()); // in case something did blow up
}
if (mysql_num_rows($result) == 0) {
... wrong verification ...
}
mysql_select_db('user_info') or die(mysql_error());
$query = "select * from personal where vercode='$vercode' and ckey='$ckey'";
$result = mysql_query($query, $db) or die(mysql_error());
if(mysql_num_rows($result) > 0)
return 'registration confirmed';
return 'wrong verification , send it again!';
Please note that you need to secure your variables $vercode and $ckey. mysql_real_escape_string() was used to be the escape method, but now mysql_real_escape_string(), and most of the functions you used will be deprecated starting php 5.5.0. Alternatively you can use PDO prepared statements

PHP/MySQL - Prepared Statements - Is the usage in this example correct?

I am creating an part of a website that deals with confirmation of a user subscribing to a newsletter.
I am having trouble with the usage on prepared statements when selecting data.
This is basically a check against information that was sent to the user in an email and retrieved by getting the info from the entered url.
So there is a string or 'key' in the database that is sent to the user in an email as a link to a page on my site with the users details appended to the url. The script checks to see if these keys match
The problem is that when I run the script it will trigger an error. This says "wrong key".
The key in the database ($dbkey) is the same as the key provided in the email link. which is the same key that is made into $key. The problem though, is that in the while loop an error is being triggered and $dbkeyis not being passed the data from the database :
Notice: Trying to get property of non-object in C:\wamp\www\site\script.php on line 35
The sql statement when run in phpmyadmin does return the correct result set.
Here is the code:
$confirm= sanitize($_GET['confirm']);
$stmt = $link->prepare("SELECT id, dbkey FROM specials WHERE id = ?");
if (!$stmt)
{
$error = "{$link->errno} : {$link->error}";
include "$docRoot/html/main/error.html.php";
exit();
}
if (!$stmt->bind_param("i", $confirm))
{
$error = "{$stmt->errno} : {$stmt->error}";
include "$docRoot/html/main/error.html.php";
exit();
}
if (!$stmt->execute())
{
$error = "{$stmt->errno} : {$stmt->error}";
include "$docRoot/html/main/error.html.php";
exit();
}
$stmt->store_result();
if ($stmt->num_rows)
{
while ($row = $stmt->fetch())
{
$dbKey = $row->dbkey;
}
$key= sanitize($_GET['key']);
if ($dbKey !== $key)
{
echo 'wrong key';
}
}
else
{
echo 'not in database';
}
I would like to say that all other scripts connecting to the database in this manner do work, but this was the first time I have used prepared statements to select data. I wonder if this problem is caused by an error in my coding, hence the reason why I have posted this question.
If anyone could spot where I have gone wrong here, or possibly possibly provide some advice on how I would debug the code to see what exactly the error is that would be greatly appreciated!
Thanks!!
EDIT: The problem simply is the $key returns a string but $dbkey returns empty
EDIT2:
if ($stmt = $link->prepare("SELECT id, verified, dbkey FROM specials WHERE id=?")) {
$stmt->bind_param("i", $confirm);
$stmt->execute();
$stmt->bind_result($dbId, $dbVerified, $dbKey);
$stmt->fetch();
$stmt->close();
if ($dbKey !== $key)
{
echo 'wrong key';
}
else if ($dbVerified == 1)
{
echo 'already activated';
}
else if ($dbKey == $key && dbVerified == 0)
{
echo 'success';
}
}
else
}
echo 'user not in db';
}
$stmt->fetch() just returns a boolean indicating whether it was successful, not an object whose properties are the current row's fields. You need to call $stmt->bind_result() to specify into which variables you want the fields to be placed.
The approach taken in your second edit looks good, except that the test for whether the user is in the database should be onfetch(), not prepare() (or else use num_rows as you had previously). Thus:
if ($stmt = $link->prepare("SELECT id, verified, dbkey FROM specials WHERE id=?"))
{
$stmt->bind_param("i", $confirm);
$stmt->execute();
$stmt->bind_result($dbId, $dbVerified, $dbKey);
if ($stmt->fetch())
{
if ($dbVerified == 1)
{
echo 'already activated';
}
else if ($dbKey !== $key)
{
echo 'wrong key';
}
else if ($dbKey == $key && dbVerified == 0)
{
echo 'success';
}
}
else
}
echo 'user not in db';
}
$stmt->close();
}

Categories