I've made a user class which validates the data passed through the form and then subsequently updates the database table users. I want to add extra functionality such as checking if the username and email exists in the table, I've added a little script however it doesn't seem to be working.
I inserted a duplicated email address and I did not get the error message "email exists" instead I get the success message "1 row inserted":
Am I doing something wrong below? Is there perhaps a better way to approach this?
public function insert() {
if (isset($_POST['submit'])) {
$email = isset($_POST['email']) ? $this->mysqli->real_escape_string($_POST['email']) : '';
$result = $this->mysqli->prepare("SELECT * FROM users WHERE email='".$email."'");
if ($result->num_rows) {
echo "email exisits!";
}
else
{
$stmt = $this->mysqli->prepare("INSERT INTO users (username, password, name, email) VALUES (?, ?, ?, ?)");
$stmt->bind_param('ssss', $username, $password, $name, $email); // bind strings to the paramater
//escape the POST data for added protection
$username = isset($_POST['username']) ? $this->mysqli->real_escape_string($_POST['username']) : '';
$cryptedPassword = crypt($_POST['password']);
$password = $this->mysqli->real_escape_string($cryptedPassword);
$name = isset($_POST['name']) ? $this->mysqli->real_escape_string($_POST['name']) : '';
$email = isset($_POST['email']) ? $this->mysqli->real_escape_string($_POST['email']) : '';
/* execute prepared statement */
$stmt->execute();
printf("%d Row inserted.\n", $stmt->affected_rows);
/* close statement and connection */
$stmt->close();
}
You are using the worst API you ever can choose.
With safeMysql it would be
$exists = $this->db->getOne("SELECT 1 FROM users WHERE email=?s", $_POST['email']);
if ($exists) {
echo "email exisits!";
}
With PDO it is slightly longer but usable
$stmt = $this->db->prepare("SELECT 1 FROM users WHERE email=?");
$stmt->execute(array($_POST['email']));
$exists = $stmt->fetchColumn();
if ($exists)
{
echo "email exisits!";
}
But with raw mysqli you will need a screenful of code only to check if user exists.
So, the whole function using safeMysql would be
public function insert()
{
if (!isset($_POST['submit'])) {
return FALSE;
}
$sql = "SELECT 1 FROM users WHERE email=?s";
$exists = $this->db->getOne($sql, $_POST['email']);
if ($exists)
{
echo "email exisits!";
return FALSE;
}
$sql = "INSERT INTO users SET ?u";
$allowed = array('username', 'name', 'email');
$insert = $this->db->filterArray($_POST, $allowed);
$insert['password'] = crypt($_POST['password']);
$this->db->query($sql, $insert);
return $this->db->afectedRows();
}
you need to use this code after prepare statement
$stmt->execute();
$stmt->store_result();
put this
if ($result->num_rows > 0) {
echo "email exisits!";
}
instead of
if ($result->num_rows) {
echo "email exisits!";
}
First, you are using prepare (great!) but then you are just passing in the value of email, effectively defeating the benefit of prepared statements.
Second, you never execute the query, which is why you don't get anything in num_rows.
public function insert() {
$result = $this->mysqli->prepare("SELECT COUNT(*) FROM users WHERE email=?");
$result->bind_param("s", $_POST['email']);
$result->execute();
$result->bind_result($email_count);
if ($email_count) {
echo "email exisits!";
} else {
# your other logic
From what I can see you're not assigning a value to num_rows prior to testing it with if ($result->num_rows), so it will always be 0
Related
I'm trying to select things from my database and echo them. For some reason the only thing I can echo is the email. The id and the username doesn't show up. I don't get any errors, they just don't appear.
$sql = "SELECT id, email, username FROM users WHERE email = ?";
if ($stmt = mysqli_prepare($link, $sql)) {
mysqli_stmt_bind_param($stmt, "s", $param_email);
$param_email = $email;
if (mysqli_stmt_execute($stmt)) {
mysqli_stmt_store_result($stmt);
if (mysqli_stmt_num_rows($stmt) == 1) {
mysqli_stmt_bind_result($stmt, $id, $email, $username);
$error = 0;
$to = $email;
echo "id:".$id;
echo $username;
echo $email;
} else {
//some stuff
}
} else {
$error = 1;
}
}
What Am I missing?
The reason why you cannot see any values fetched from the database is because you forgot to call fetch() after bind_result().
However, you are overcomplicating things. You do not need so many if statements and you should not use bind_result() if you have more than one column. This gets very messy. Use get_result() to fetch the results and then fetch the single row you need(assuming email is unique and your SELECT returns 0 or 1 records).
$stmt = $link->prepare("SELECT id, email, username FROM users WHERE email = ?");
$stmt->bind_param('s', $email);
$stmt->execute();
$result = $stmt->get_result()->fetch_assoc();
if ($result) {
$error = 0;
$to = $result['email'];
echo "id:".$result['id'];
echo $result['username'];
echo $result['email'];
} else {
$error = 1;
}
There is no need for mysqli_stmt_num_rows. The data itself tells you if something was returned or not. This also protects you from a similar problem when using unbuffered queries. It is easy to accidentally omit mysqli_stmt_store_result().
Never check the return value of mysqli_stmt_execute() or mysqli_prepare(). This is a terrible and messy practice. Ensure you have error reporting switched on. See How to get the error message in MySQLi?
I've created a login activity and there are two edittext ids and passwords. I have a PHP code which checks the user with their id and password. If both are correct then it transfers to the other activity, but here I want a PHP code which checks the id with their specific password. If the user enters a correct id but enters an incorrect password, then it should produce an error "pls enter correct password".
Please suggest me a correct PHP code for this.
<?php
require "r_connect.php";
if($_SERVER['REQUEST_METHOD']=='POST')
{
$rollno=$_POST['rollno'];
$password=$_POST['password'];
$sql = "SELECT * FROM registration_user WHERE rollno = '$rollno' AND password='$password'";
$result = mysqli_query($connect,$sql);
$check = mysqli_fetch_array($result);
if(isset($check))
{
echo 'Success';
}
else
{
echo 'Error';
}
}
?>
Try below code for PHP:
<?php
require "r_connect.php";
if($_SERVER['REQUEST_METHOD']=='POST')
{
$rollno = $_POST['rollno'];
$password = $_POST['password'];
$sql = "SELECT password FROM registration_user WHERE rollno = '$rollno'";
$result = mysqli_query($connect,$sql);
$check = mysqli_fetch_array($result);
if(mysqli_num_rows($check) > 0)
{
if($check["password"] == $password){
echo 'Success';
}else{
echo 'pls enter correct password';
}
}
else
{
echo 'Invalid id';
}
}
?>
You can also refer this tutorial for more information
Split your SQL statement into to, at first query WHERE rollno = '$rollno', if found go on and query WHERE rollno = '$rollno' AND password = '$password', if everything's correct go on, if first statement fails user is not found, if second query fails, the user is found but password is not matching, this is your desired case.
When writing an authentication flow you can keep following things in mind :
validate your input data well
when interacting with Select queries use prepared statements whenever possible
use sha1 and md5 combinations on the password string to store in the database and comparisons.
I have tried to implement these things in the following code, of course there's always scope for improvement
function checkRollno($conn, $rollno)
{
$stmt = mysqli_stmt_init($conn);
$prepareQuery = "SELECT count(*) FROM tablename WHERE rollno = ?";
//Prepared Statements
if( mysqli_stmt_prepare($stmt, $prepareQuery ) )
{
// Bind params
mysqli_stmt_bind_param($stmt, 'i', $rollno);//i is for integer
/* execute query */
mysqli_stmt_execute($stmt);
/* Fetch Result */
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_assoc($result);
/* close statement */
mysqli_stmt_close($stmt);
if( count($row) < 1 )
return false;
else
return true;
}
else
return false;
}
function checkUserExists($conn, $rollno, $pass)
{
$stmt = mysqli_stmt_init($conn);
$prepareQuery = "SELECT count(*) FROM tablename WHERE rollno = ? AND password= ?";
//Compare sha1 of md5 of your password (You should not store or check against exact password strings)
$pass = sha1(md5($pass));
//Prepared Statements
if( mysqli_stmt_prepare($stmt, $prepareQuery ) )
{
// Bind params
mysqli_stmt_bind_param($stmt, 'is', $rollno, sha1(md5($pass)));// s is for strings
/* execute query */
mysqli_stmt_execute($stmt);
/* Fetch Result */
$result = mysqli_stmt_get_result($stmt);
$row = mysqli_fetch_assoc($result);
/* close statement */
mysqli_stmt_close($stmt);
if( count($row) < 1 )
return false;
else
return true;
}
else
return false;
}
//Main Block
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
{
if( isset($_POST['rollno']) && $_POST['rollno'] != '' )
$rollno = $_POST['rollno'];
if( isset($_POST['password']) && $_POST['password'] != '' )
$pass = $_POST['password'];
$res = checkRollno($conn, $rollno);
if( $res )//rollno exists
{
if( checkUserExists( $conn, $rollno, $pass ) )
die('authenticated');//Authenticated
else
die('denied');//Wrong password
}
else//rollno doesn't exist
{
//code to reflect wrong id does not exist
}
}
I am sure you can use better function names :)
Prepared Statements
Your code could look like this :
$sql = "SELECT * FROM registration_user WHERE rollno = '$rollno'";
$result = mysqli_query($connect,$sql);
$check = mysqli_fetch_array($result);
Then you can do checks :
if(mysqli_num_rows($check) > 0)
{
if($check['password']===$password){
//id and pass correct
}else{
// id correct , but bad password
}
}else
{
echo 'Invalid id';
}
$valid = mysqli_query($com,"select username,email from company_profile where username = ".$uname." or email = ".$email." ");
if ($valid=="")
{echo "email n username exists";}
else
{
echo "reg success";
}
Here is my code, it doesn't work is i was also sure. want to return result weather email or username exists in db or not.
what's the way to do it.
The mysqli_query method returns a resultset, not a scalar.
$result = mysqli_query($com, "SELECT ...", MYSQLI_STORE_RESULT);
if ( $result->num_rows() > 0 ) {
echo "query returned at least one row";
}
The code looks vulnerable to SQL injection, we don't see any references to the mysqli_real_escape_string function.
We'd prefer to see a prepared statement with bind variables, e.g.
if ($stmt = mysqli_prepare($com, "SELECT username,email from company_profile"
. " where username = ? OR email = ? "))
{
mysqli_stmt_bind_param($stmt, "ss", $uname, $email);
mysqli_stmt_execute($stmt);
$result = mysqli_stmt_get_result($stmt);
while ($row = mysqli_fetch_array($result))
{
}
mysqli_stmt_close($stmt);
}
I've started a thread or two so far but nothing has got resolved. I'm not able to use the mysqlnd because i'm using a shared hosting account with godaddy.
All i need to do is check if my email address and/or username is in use; if they are in use throw and error, if not.. all is well.
Here is my code:
$input_errors = array();
if (!empty($_POST['username'])) {
$user = $_POST['username'];
} else {
$input_errors['username'] = "Must fill out username";
}
$email = filter_input(INPUT_POST, 'usermail', FILTER_VALIDATE_EMAIL);
if (false === $email) {
$input_errors['usermail'] = "Not a valid email address";
}
if(count($input_errors) > 0) {
print_r($input_errors); die();
}
$sql = "SELECT COUNT(*) as amount FROM people WHERE username = ?
OR email = ?";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("ss", $user, $email);
$stmt->execute();
$results = $stmt->get_result();
$data = mysqli_fetch_assoc($results);
if ($data['amount'] > 0)
{
print "User already exists";
}
}
else {
$stmt = $mysqli->stmt_init();
if (!$stmt) {
echo "Init failed";
} else {
$cmd = "INSERT INTO people (username, email, sign_up_date) VALUES (?, ?, NOW() )";
if ($stmt->prepare($cmd)) {
$stmt->bind_param('ss', $user, $email );
$stmt->execute();
echo $stmt->affected_rows . " row(s) inserted";
$stmt->close();
} else {
echo "Prepare failed";
}
mysqli_close($mysqli);
}
}
bind_result() does not work.
Change your sql statement to the following:
$sql = "SELECT COUNT(*) as amount FROM people WHERE username = '".mysqli_real_escape_string($_POST['username'])."' OR email = '".mysqli_real_escape_string($email)."'";
This question already has answers here:
Fatal error: Call to undefined method mysqli_stmt::get_result()
(2 answers)
Closed 9 years ago.
I'm not sure why I keep getting this error but I need some help with it... I'm just trying to check the db to see of the record exists before allowing an insert.
$input_errors = array();
if (!empty($_POST['username'])) {
$user = $_POST['username'];
} else {
$input_errors['username'] = "Must fill out username";
}
$email = filter_input(INPUT_POST, 'usermail', FILTER_VALIDATE_EMAIL);
if (false === $email) {
$input_errors['usermail'] = "Not a valid email address";
}
if(count($input_errors) > 0) {
print_r($input_errors); die();
}
$sql = "SELECT COUNT(*) as amount FROM people WHERE username = ?
OR email = ?";
if ($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("ss", $user, $email);
$stmt->execute();
$results = $stmt->get_result();
$data = mysqli_fetch_assoc($results);
if ($data['amount'] > 0)
{
print "User already exists";
}
}
else {
$stmt = $mysqli->stmt_init();
if (!$stmt) {
echo "Init failed";
} else {
$cmd = "INSERT INTO people (username, email, sign_up_date) VALUES (?, ?, NOW() )";
if ($stmt->prepare($cmd)) {
$stmt->bind_param('ss', $user, $email );
$stmt->execute();
echo $stmt->affected_rows . " row(s) inserted";
$stmt->close();
} else {
echo "Prepare failed";
}
mysqli_close($mysqli);
}
}
If anyone can lend a helping hand that would be fantastic.
For some reason I just can't stand such long and windy codes.
All you actually need is just
$cmd = "INSERT IGNORE INTO people (username, email, sign_up_date) VALUES (?, ?, NOW() )";
$stmt->prepare($cmd);
$stmt->bind_param('ss', $user, $email);
$stmt->execute();
if (!$stmt->affected_rows)
{
print "User already exists";
}
No need to hassle with extra select query.
No need to hassle with binding results.
No need to hassle with numerous nested if statements (whose logic is flawed and actually spoiled the whole mess).
Make sure your php version is PHP 5.3.0 or higher and you have the mysqlnd driver installed on your server. Otherwise, that function is not available.
Instead, you could use fetch().