What is wrong with my Register function? - php

Problem & Explanation
Hello I have just coded a function that first does checking if account exists in database with that name, and then if email exists in database with that entered email.
If not, return true + insert data.
But in this case, nothing happens on submit, it just shows the form, but doesn't inserts the data..
What is wrong with it?
function createAccount($name, $password, $email)
{
global $pdo;
$check_in = $pdo->prepare("SELECT * FROM users WHERE user_name = :username LIMIT 1");
$check_in->execute( array(':username' => $name) );
if (!$check_in->rowCount())
{
$check_in = email_exists($email);
if ($check_in === false)
{
$insert_in = $pdo->prepare
("
INSERT INTO
users
(user_name, user_password, user_email)
VALUES
(:name, :password, :email)
");
$insert_in->execute( array
(
':name' => $name,
':password' => $password,
':email' => $email
));
return true;
}
else
{
return 'exists';
}
}
else
{
return 'user_in_use';
}
}
function email_exists($email)
{
global $pdo;
$check = $pdo->prepare("SELECT * FROM users WHERE user_email = :email LIMIT 1");
$check->execute( array(':email' => $email) );
if ($check->rowCount())
{
return true;
}
else
{
return false;
}
}
This is how I make up the register:
# Creating shortcuts
if (isset($_POST['username']) && isset($_POST['password']) && isset($_POST['email']))
{
$name = $_POST['username'];
$password = $_POST['password'];
$email = $_POST['email'];
}
# Creating errors array
$errors = array();
if (isset($_POST['submit']))
{
$check_in = createAccount($name, $password, $email);
if ($check_in === true)
{
echo 'Created account sucessfully!';
}
else if ($check_in == 'already_in_use')
{
echo 'Could not create account because name already in use..';
}
else if($check_in == 'exists')
{
echo 'Email already in use..';
}
}
Question:
What is wrong with this code & how do I fix this? I have no errors at all.
It just won't insert any data to the Database.
Yes, the PDO connection & statements are right, because the login works perfectly.
Thanks a lot!
EDIT!
if ($check_in === true)
{
echo 'Created account sucessfully!';
}
else if ($check_in == 'already_in_use')
{
echo 'Could not create account because name already in use..';
}
else if($check_in == 'exists')
{
echo 'Email already in use..';
} else {
echo 'Error is there...';
}
It's echoing 'Error is there...' apon submit!

I just want to slap myself!.....
The problem was: The fields were set as INT, therefore we could not store anything but ints...

Related

Check if user exists Registration

I am building a social app in Corona SDK with PHP being the back-end.
I am trying to sign up to the app but a block of code is getting skipped over.
if (!$errors) {
$stmt = $con->prepare("SELECT username, email FROM users WHERE username=? OR email=?");
$stmt->bind_param("ss", $_POST['username'], $_POST['email']);
$stmt->execute();
foreach ($stmt->get_result() as $row) {
foreach (['username', 'email'] as $field) {
if ($row[$field] == $_POST[$field]) {
echo "Sorry, that " . $field . " is already in use.";
die();
}
}
}
}
That code checks if the username or email that was entered is already in the DB. It works fine with my website but it doesn't work with the app. I commented out all of the other echo statements and verified that that specific block of code just doesn't run. Can someone help me ?
/*if ($_SERVER['REQUEST_METHOD'] != 'POST' || ! isset($_POST['Register'])) {
// Use full absolute URL header('Location: https://www.yoursite.com/index.php');
//header('Location: index.php');
echo "Not POST";
die();
} */
require 'config/connect.php';
$con = new mysqli(...$dbCredentials);
$username = $_POST['username'] ?? '';
$email = $_POST['email'] ?? '';
$pw = $_POST['pw'] ?? '';
$errors = [];
if (!trim($username)) {
echo 'Fill in username to sign up';
die();
}
if (!preg_match("/^[a-zA-Z0-9]{5,}$/", $username)) {
echo 'Invalid username, only letters and/or digits.';
die();
}
if (!trim($pw)) {
echo 'Fill in password to sign up';
die();
}
if (!trim($email)) {
echo 'Fill in email to sign up';
die();
}
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo 'Invalid email';
die();
}
if (!$errors) {
$stmt = $con->prepare("SELECT username, email FROM users WHERE username=? OR email=?");
$stmt->bind_param("ss", $_POST['username'], $_POST['email']);
$stmt->execute();
foreach ($stmt->get_result() as $row) {
foreach (['username', 'email'] as $field) {
if ($row[$field] == $_POST[$field]) {
echo "Sorry, that " . $field . " is already in use.";
die();
}
}
}
}
$ipAddress = $_SERVER['REMOTE_ADDR'];
if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
$ipAddress = array_pop(explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']));
}
if (!$errors) {
$pw = password_hash($_POST['pw'], PASSWORD_BCRYPT, ['cost' => 14]);
$stmt = $con->prepare("INSERT INTO users (username, email, pw, ip_address)
VALUES (?, ?, ?, ?)");
$stmt->bind_param("ssss", $username, $email, $pw, $ipAddress);
$stmt->execute();
$_SESSION["user_id"] = $_POST['username'];
echo "success";
die();
} else {
echo 'something is wrong here.';
die();
}
$_SESSION['error'] = '<b><p style="color: #fff; font-size: 30px; top: 34%;right: 50%;position: absolute;">
' . $errors . '</p></b>';
//header('Location: index.php');
//exit();
You should the early returns concept. First check if there are errors, show error message and exit. If there are no errors then move ahead further to the desired case. This may help.
if ($errors) {
echo 'something is wrong here.';
die();
}
Too complicated! I would simplified that like:
SELECT COUNT(`username`) FROM `users` WHERE username=? OR email=?;
$stmt->bind_param("ss", $username, $email);
In PDO there is a function called fetchColumn() to get the count as int. Its either 0 or 1. There should be a similar function in mysqli. I think it's mysqli_fetch_field()
username, password and email can simplified as well:
if (empty(trim($username)) or !ctype_alnum($username))
{ die('Username is either empty or invalid! Only alphanumeric characters'); }
if (empty(trim($pw)))
{ die('Fill in password to sign up'); }
if (empty(trim($email)) or !filter_var($email, FILTER_VALIDATE_EMAIL))
{ die('Email is either empty or not a valid address!'); }
if (!$errors) { can't be false
$pw = password_hash($pw);
never store username in session always user id its way safer!
If this should not work try to place an var_dump($errors) before sql check.
If this should not work check database connection and bind params values

Can't get user input in to password_verify()

here is the login code, I'm trying to get password verify to work but It doesn't want to. It seems like this count($sql->fetchAll()) > 0 is the problem or that I am calling the wrong variable to the password_verify().
$signup = isset($_POST['signup'] ) ? $_POST['signup'] : false;
$submit = isset( $_POST['submit'] ) ? $_POST['submit'] : false;
$username = isset( $_POST['username'] ) ? $_POST['username'] : false;
$password = isset( $_POST['password'] ) ? $_POST['password'] : false;
if( $submit && $username && $password ) {
$sql = $DB_con->prepare( "SELECT * FROM users WHERE user_name=:user_name AND user_pass=:user_pass" );
$sql->bindParam( ':user_name', $username, PDO::PARAM_STR );
$sql->bindParam( ':user_pass', $password, PDO::PARAM_STR );
$check_user=$sql->fetch(PDO::FETCH_ASSOC);
$success = $sql->execute();
$verify = password_verify($password, check_user['user_pass']);
// Successfully logged in!
if($success && count($sql->fetchAll()) > 0 && $verify) {
$_SESSION['logged_in'] = true;
// Unset errors
unset($_SESSION['error']);
}
else {
// display an error
$_SESSION['error'] = 'That user doesn\'t exist';
}
}
else {
//displays error
$_SESSION['error'] = 'Please enter all fields';
}
if($signup) {
header('Location: signup.php');
}
exit;
Here is the signup code
function register($uname,$umail,$upass)
{
$DB_con = null;
try
{
$DB_con = new PDO("mysql:host=$host;dbname=$dbname", "$username" ,"$password");
$DB_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
echo $e->getMessage();
}
try
{
$new_password = password_hash($upass, PASSWORD_DEFAULT);
$stmt = $DB_con->prepare("INSERT INTO users(user_name,user_email,user_pass)
VALUES(:uname, :umail, :upass)");
$stmt->bindparam(":uname", $uname);
$stmt->bindparam(":umail", $umail);
$stmt->bindparam(":upass", $new_password);
$stmt->execute();
return $stmt;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
There are several things that needs to be cleaned up with this piece of code.
Let's start with your register() function. There's a clear syntax-error here (where you make the connection), the ""$password". Then that function don't know what $dbname, $username or $password are (for the connection), these variables aren't in the scope of the function (it can see it). Usually it's better to pass the connection object as a parameter, not create a new object for each time you call the register() function. Modified for that and cleaned a bit, it would look like this
function register($DB_con, $uname ,$umail, $upass) {
try {
$new_password = password_hash($upass, PASSWORD_DEFAULT);
$stmt = $DB_con->prepare("INSERT INTO users (user_name, user_email, user_pass)
VALUES (:uname, :umail, :upass)");
$stmt->bindparam(":uname", $uname);
$stmt->bindparam(":umail", $umail);
$stmt->bindparam(":upass", $new_password);
return $stmt->execute();
} catch(PDOException $e) {
echo $e->getMessage();
}
}
and be used like
register($DB_con, 'Nader', 'example#example.com', 'pa$$w0rd'); // True or false
Then onto your sign-in. This is a little messy, and you're doing a few things wrong. What I've found so far is...
Fetching after execution
Selecting WHERE the unhashed password is equal to the hashed one (won't return any rows)
count($sql->fetchAll()) > 0 will be zero, because you already fetched once, and there will only be one user => this means one row. Fetching one means there are no more to fetch, so fetchAll() is empty!
You don't need to do any more checks than if ($check_user=$sql->fetch()) to check if there are rows
Corrected and accounted for the points above, your code would look something like this
$signup = isset($_POST['signup']) ? $_POST['signup'] : false;
$submit = isset($_POST['submit']) ? $_POST['submit'] : false;
$username = isset($_POST['username']) ? $_POST['username'] : false;
$password = isset($_POST['password']) ? $_POST['password'] : false;
if ($submit && $username && $password) {
$sql = $DB_con->prepare("SELECT * FROM users WHERE user_name=:user_name");
$sql->bindParam(':user_name', $username, PDO::PARAM_STR);
$sql->execute();
if ($check_user=$sql->fetch(PDO::FETCH_ASSOC)) {
if (password_verify($password, $check_user['user_pass'])) {
$_SESSION['logged_in'] = true;
// Unset errors
unset($_SESSION['error']);
} else {
// Invalid password
}
} else {
// No user with that username
}
} else {
//displays error
$_SESSION['error'] = 'Please enter all fields';
}
if ($signup) {
header('Location: signup.php');
}
exit;
This assumes unique usernames in the DB
There might be more issues which I can't see, which is why you should enable error-reporting by adding
<?php
error_reoprting(E_ALL);
ini_set("display_errors", 1);
at the top of your file (errors shouldn't be displayed like that in a live environment).

How to check if username already exist using PDO?

am currently working on a project and i have the script for insertion.my table is called survey and the fields are id,username,password,province. the username is set to unique key. the insertion process is working fine without any duplicate entry but when i try to insert a duplicate entry at always shows me this error
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'bluff' for key 'username'
I know what this error mean, my problem is that how can i can if username already exist or not i want an alert message to pop up..
here is my code
class.user.php
public function username($username){
$stmt = $this->db->prepare("SELECT count(*) FROM tish_images WHERE username = :username");
$stmt->execute(array($username));
$number_of_rows = $result->fetchColumn();
if($number_of_rows >= 1) {
echo 'username does exist'; // or return so you get the value
} else {
echo 'username does not exist'; //also return?
}
}
public function create($username,$password,$province)
{
try
{
$stmt = $this->db->prepare("INSERT INTO tish_images(username,password,province) VALUES(:username, :password, :province)");
$stmt->bindparam(":username",$username);
$stmt->bindparam(":password",$password);
$stmt->bindparam(":province",$province);
$stmt->execute();
return true;
}
catch(PDOException $e)
{
echo $e->getMessage();
return false;
}
}
index.php
<?php
include_once 'DB.php';
$username = isset($_GET['username']) ? $_GET['username'] : '';
$password = isset($_GET['password']) ? $_GET['password'] : '';
$province = isset($_GET['province']) ? $_GET['province'] : '';
if(isset($_FILES['files'])){
$id = $_GET['id'];
$username = $_POST['username'];
$password = $_POST['password'];
$province = $_POST['province'];
if($crud->upload($id,$FILE_NAME,$FILE_SIZE,$FILE_TYPE,$username,$password,$province))
{
echo "<script type='text/javascript'>alert('Successfully Updated!');</script>";
}
else
{
echo "<script type='text/javascript'>alert('Updating Failed!');</script>";
}
}
if(isset($_GET['id']))
{
$id = $_GET['id'];
extract($crud->getID($id));
}
You should run a SELECT before performing the query to see if the username exists.
// count how many rows with user name exists
$checkUserStmt = $this->db->prepare("
SELECT count(1)
FROM tish_images
WHERE username = :username
");
$checkUserStmt->execute(array(":username" => $username));
// fetch the count result
if ($checkUserStmt->fetchColumn() > 0) {
// username already exists
} else {
// username available
} //if
A few notes.
You still might get a duplicate entry error if you have two users trying to register the same username at close interval.
You should hash the password see Secure hash and salt for PHP passwords
To check if username or email already exists. I added email in there as this is also useful. You don't want two users with the same email address. Well I wouldn't see the need for it. :)
Complete code added and up to date.
$query_check_user_name = $this->db_connection->prepare('SELECT user_name, user_email FROM users WHERE user_name=:user_name OR user_email=:user_email');
$query_check_user_name->bindValue(':user_name', $user_name, PDO::PARAM_STR);
$query_check_user_name->bindValue(':user_email', $user_email, PDO::PARAM_STR);
$query_check_user_name->execute();
$result = $query_check_user_name->fetchAll();
if ($result > 0) {
echo "Someone with that username/email already exists.";
} else {
//Continue with proccessing the form
}
OR
$query_check_user_name = $this->db_connection->prepare('SELECT user_name, user_email FROM users WHERE user_name=:user_name OR user_email=:user_email');
$query_check_user_name->bindValue(':user_name', $user_name, PDO::PARAM_STR);
$query_check_user_name->bindValue(':user_email', $user_email, PDO::PARAM_STR);
$query_check_user_name->execute();
$result = $query_check_user_name->fetchAll();
if ($result > 0) {
return true;
} else {
return false;
}

usercake updating field isn't working

I use User Cake for user management system but I am struggling with one problem, I have had asked this question in their website but I couldn't find anyone to help me out.
What I need is simply making the users be able to update their information. ex. first name, phone, email....The email field updates correctly as it came with that functionality.
The fields that I added aren't being updated. Can someone give me some hints on what I am missing?
Here is what I tried looking at the email field. I have First Name field.
Funcs.php
//Update a user's email
function updateEmail($id, $email)
{
global $mysqli,$db_table_prefix;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."users
SET
email = ?
WHERE
id = ?");
$stmt->bind_param("si", $email, $id);
$result = $stmt->execute();
$stmt->close();
return $result;
}
//Update a user's first name. This is what isn't working.
function updateFirstname($id, $firstname)
{
global $mysqli,$db_table_prefix;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."users
SET
firstname = ?
WHERE
id = ?");
$stmt->bind_param("si", $firstname, $id);
$result = $stmt->execute();
$stmt->close();
return $result;
}
Here is class.user.php
class loggedInUser {
public $email = NULL;
public $hash_pw = NULL;
public $user_id = NULL;
public $firstname = NULL;
//Update a users email
public function updateEmail($email)
{
global $mysqli,$db_table_prefix;
$this->email = $email;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."users
SET
email = ?
WHERE
id = ?");
$stmt->bind_param("si", $email, $this->user_id);
$stmt->execute();
$stmt->close();
}
//Update a users first name
public function updateFirstname($firstname)
{
global $mysqli,$db_table_prefix;
$this->firstname = $firstname;
$stmt = $mysqli->prepare("UPDATE ".$db_table_prefix."users
SET
firstname = ?
WHERE
id = ?");
$stmt->bind_param("si", $firstname, $this->user_id);
$stmt->execute();
$stmt->close();
}
}
user_settings.php where I can change the fields and hit the update button. If I change the email and hit update, the email is updated but when I change firstname and hit update I get
nothing to update
//Prevent the user visiting the logged in page if he is not logged in
if(!isUserLoggedIn()) { header("Location: login.php"); die(); }
if(!empty($_POST))
{
$errors = array();
$successes = array();
$password = $_POST["password"];
$password_new = $_POST["passwordc"];
$password_confirm = $_POST["passwordcheck"];
$errors = array();
$email = $_POST["email"];
$firstname = $_POST["firstname"];
//Perform some validation
//Feel free to edit / change as required
//Confirm the hashes match before updating a users password
$entered_pass = generateHash($password,$loggedInUser->hash_pw);
if (trim($password) == ""){
$errors[] = lang("ACCOUNT_SPECIFY_PASSWORD");
}
else if($entered_pass != $loggedInUser->hash_pw)
{
//No match
$errors[] = lang("ACCOUNT_PASSWORD_INVALID");
}
if($email != $loggedInUser->email)
{
if(trim($email) == "")
{
$errors[] = lang("ACCOUNT_SPECIFY_EMAIL");
}
else if(!isValidEmail($email))
{
$errors[] = lang("ACCOUNT_INVALID_EMAIL");
}
else if(emailExists($email))
{
$errors[] = lang("ACCOUNT_EMAIL_IN_USE", array($email));
}
//End data validation
if(count($errors) == 0)
{
$loggedInUser->updateEmail($email);
$loggedInUser->updateFirstname($firstname);
$successes[] = lang("ACCOUNT_EMAIL_UPDATED");
}
}
if ($password_new != "" OR $password_confirm != "")
{
if(trim($password_new) == "")
{
$errors[] = lang("ACCOUNT_SPECIFY_NEW_PASSWORD");
}
else if(trim($password_confirm) == "")
{
$errors[] = lang("ACCOUNT_SPECIFY_CONFIRM_PASSWORD");
}
else if(minMaxRange(8,50,$password_new))
{
$errors[] = lang("ACCOUNT_NEW_PASSWORD_LENGTH",array(8,50));
}
else if($password_new != $password_confirm)
{
$errors[] = lang("ACCOUNT_PASS_MISMATCH");
}
//End data validation
if(count($errors) == 0)
{
//Also prevent updating if someone attempts to update with the same password
$entered_pass_new = generateHash($password_new,$loggedInUser->hash_pw);
if($entered_pass_new == $loggedInUser->hash_pw)
{
//Don't update, this fool is trying to update with the same password ¬¬
$errors[] = lang("ACCOUNT_PASSWORD_NOTHING_TO_UPDATE");
}
else
{
//This function will create the new hash and update the hash_pw property.
$loggedInUser->updatePassword($password_new);
$successes[] = lang("ACCOUNT_PASSWORD_UPDATED");
}
}
}
if(count($errors) == 0 AND count($successes) == 0){
$errors[] = lang("NOTHING_TO_UPDATE");
}
}
if($email != $loggedInUser->email)
{
if(trim($email) == "")
{
$errors[] = lang("ACCOUNT_SPECIFY_EMAIL");
}
else if(!isValidEmail($email))
{
$errors[] = lang("ACCOUNT_INVALID_EMAIL");
}
else if(emailExists($email))
{
$errors[] = lang("ACCOUNT_EMAIL_IN_USE", array($email));
}
//End data validation
if(count($errors) == 0)
{
$loggedInUser->updateEmail($email);
$successes[] = lang("ACCOUNT_EMAIL_UPDATED");
}
}
Clone this function as
if($firstname != $loggedInUser->firstname) blah blah
Remove this line from the function above move it in the new function:
loggedInUser->updateFirstname($firstname);
Just clone the function,just as you have done above.Change the error messages and add function to validate the name,it will be somewhat different,it will require more work.

Issue with Form and PDO

I plan to clean up the code, and make it more OOP friendly later, but for now I am struggling to get this to work. I have managed to get down for it to echo 'hi', but the execute doesn't seem to be putting anything into the database, and it is not giving me any errors. The code is
public function newAccount(array $data) {
$error = NULL;
//Check first name length, and make sure its over 2 characters
if (strlen($data['fname']) > 2) {
$fname = $data['fname'];
}
else {
$fname = FALSE;
$error .= "Please put in a valid First Name. <br />";
}
//Check if last name length is over 2 characters
if (strlen($data['lname']) > 2) {
$lname = $data['lname'];
}
else {
$lname = FALSE;
$error .= "Please enter a valid Last Name. <br />";
}
// Check username
if (strlen($data['user']) > 3) {
$user = $data['user'];
}
else {
$user = FALSE;
$error .= "Username must be longer than 3 characters.<br />";
}
// Mske sure password is atleast 6 characters, and retyped correctly
if (strlen($data['pass']) > 5) {
if ($data['pass'] == $data['repass']) {
$pass = $data['pass'];
}
else {
$pass = FALSE;
$error .= "Passwords do not match.<br />";
}
}
else {
$pass = FALSE;
$error .= "Password must be longer than 6 characters.";
}
//make sure email looks correct, strpos makes sure there is an '#'
if (strlen($data['email']) > 5 && strpos($data['email'], '#')) {
$email = $data['email'];
}
else {
$email = FALSE;
$error .= "Please enter a valid email. <br />";
}
// Check if user is suppose to be admin
if (isset($data['admin'])) {
$admin = '1';
}
else {
$admin = '0';
}
if ($fname && $lname && $user && $pass && $email) {
echo 'hi';
try {
$sth = $this->dbc->prepare("INSERT INTO users(user, password first_name, last_name, email, admin) VALUES(:user, MD5(:pass), :fname, :lname, :email, :admin)");
$sth->execute(array(":user" => $user,
":pass" => $pass,
":fname" => $fname,
":lname" => $lname,
":email" => $email,
":admin" => $admin)
);
}
catch (PDOException $e) {
echo $e->getMessage();
}
}
else {
echo "Error" . $error;
}
}
Thanks in advance!
In your insert query, you are missing a comma after password field.
It should be
$sth = $this->dbc->prepare("INSERT INTO
users(user, password, first_name, last_name, email, admin)
VALUES(:user, MD5(:pass), :fname, :lname, :email, :admin)");
Also, when testing is entered string is email address or not, use filter_var(). Like this:
if( filter_var($data['email'], FILTER_VALIDATE_EMAIL) {
//do this...

Categories