I can not figure out why it is breaking after passing validation and not submitting to database. Just comes up with blank screen. I have echoed out the new_password and it is encrypting it properly. Am I missing something? or doing something wrong? Any help/advice is appreciated. thanks in advance.
if (isset($_POST['register'])){
//Validation and post variable stuff here but doesn't appear to be any issue with it as I have tested it alot.
}
else if(!$error_msg && !$returned_record && $_POST['register']){
function generateHash($password_1){
if(defined("CRYPT_BLOWFISH") && CRYPT_BLOWFISH){
//echo "WE HAVE CRYPT BLOWFISH";
$salt = '$2y$11$'. substr(md5(uniqid(rand(), true)), 0, 22);
return crypt($password_1, $salt);
}//End If
}//End Function generateHash();
$new_password = generateHash($password_1);
//Build our query
$sql = ("INSERT INTO members (username, email, first_name, last_name, country, password_1) VALUES (?,?,?,?,?,?)");
//Prepare our query
$stmt = $mysqli->prepare($sql) or die("PREPARE DIDNT WORK");;
//Bind the fields and there parameters to our query
$stmt->bind_param('ssssss', $username, $email, $first_name, $last_name, $country, $new_password);
//Execute the query
$stmt->execute();
header('Location: http://someurl.com');
exit();
}
Instead of binding the parameters, try this:
$sql = ("INSERT INTO members (username, email, first_name, last_name, country, password_1) VALUES (:username, :email, $first_name, :last_name, :country, :password_1)");
$stmt = $mysqli->prepare($sql) or die("Failed Execution");;
$stmt->execute(array(
':username' => $username,
':email' => $email,
':first_name' => $fname,
':last_name' => $lname,
':country' $country,
':password_1' $password
));
I think i have figured out. I was trying to implement this code into a wordpress template page with a custom loop. I removed all loop/functions and It worked first try. So something in there was causing the issues. Thanks for trying!
Related
I have a register PHP function that registers a user like so
//Function to create a new user
public function register($firstName, $lastName, $email, $state, $city, $password, $zipCode, $isHMan, $skills, $experience)
{
$password = md5($password);
$stmt = $this->conn->prepare("INSERT INTO handyman(firstName, lastName, email, state, city, password, zipCode, isHMan, skills, experience) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->bind_param("ssssssssss", $firstName, $lastName, $email, $state, $city, $password, $zipCode, $isHMan, $skills, $experience);
$result = $stmt->execute();
$stmt->close();
if ($result) {
return true;
} else {
return false;
}
}
This function works perfectly when called and everything is inserted into my handyman table (including the md5 hashed password). My problem is with my login function. This is the function:
public function login($email, $password) {
$password1 = md5($password);
$stmt = $this->conn->prepare("SELECT * FROM `handyman` WHERE email = ? AND password = ?");
$stmt->bind_param("ss", $email, $password1);
$result = $stmt->execute();
$stmt->close();
if (mysqli_num_rows($result) != 0) {
echo "results acquired";
return true;
} else {
echo "no results";
return false;
}
}
When I run this I get this warning:
Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result,
boolean given.
And the program outputs no results.
After doing a search here on stackoverflow, people were saying that this is caused by an error in the SQL query and the $result variable actually is returning a false boolean value. I input the query directly into my database with an email and password from my database and it executed perfectly. I cannot for the life of me figure out what is wrong. My values and SQL query seem to be correct. I am guessing it may have something to do with the bind_param function but I don't know what. Any help would be appreciated.
You have mixed procedural style mysqli functions with object oriented.
You'll need to adjust that code you have to this:
public function login($email, $password) {
$password1 = md5($password); // don't do this btw
$stmt = $this->conn->prepare("SELECT * FROM `handyman` WHERE email = ? AND password = ?");
$stmt->bind_param("ss", $email, $password1);
$stmt->execute();
$stmt->store_result();
if ($stmt->num_rows != 0) {
echo "results acquired";
return true;
} else {
echo "no results";
return false;
}
}
Note: In order to check num_rows you need to have called store_result first.
You also need to alter your register method too since its looking at a failure bool from execute:
public function register($firstName, $lastName, $email, $state, $city, $password, $zipCode, $isHMan, $skills, $experience)
{
$password = md5($password); // ahem .. no
$stmt = $this->conn->prepare("INSERT INTO handyman(firstName, lastName, email, state, city, password, zipCode, isHMan, skills, experience) values(?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
$stmt->bind_param("ssssssssss", $firstName, $lastName, $email, $state, $city, $password, $zipCode, $isHMan, $skills, $experience);
$stmt->execute();
$stmt->store_result();
if ($stmt->affected_rows) {
return true;
} else {
return false;
}
}
Note: Using affected_rows also needs store_result to be called. Don't check on the bool result of execute since that is used for failures in sql.
PASSWORDS:
Please look into password_hash() and password_verify() for your storage and login procedures. md5 is insecure, and out dated. Its beyond the scope of this Q/A to provide the full working usage of those functions. Please do look into them though.
I am facing an error while completing my registration system. My database connection is working properly.
Registration PHP Code:
require 'db.php';
$message = '';
if(!empty($_POST['full_name']) && !empty($_POST['email']) && !empty($_POST['username']) && !empty($_POST['password']) && !empty($_POST['confirm_password'])):
// Enter the new user in the database
$sql = "INSERT INTO users (full_name, email, username, password) VALUES (:email, :password)";
$stmt = $con->prepare($sql);
$stmt->bindParam(':email', $_POST['full_name']);
$stmt->bindParam(':email', $_POST['email']);
$stmt->bindParam(':email', $_POST['username']);
$stmt->bindParam(':password', password_hash($_POST['password'], PASSWORD_BCRYPT));
if( $stmt->execute() ):
header('Location: index.php');
$message = 'Successfully created new user';
else:
$message = 'Sorry there must have been an issue creating your account';
endif;
endif;
You are binding parameters for values which you have not included in the query,
change,
$sql = "INSERT INTO users (full_name, email, username, password) VALUES (:email, :password)";
to,
$sql = "INSERT INTO users (full_name, email, username, password) VALUES (:full_name, :email, :username, :password)";
and change,
$stmt->bindParam(':email', $_POST['full_name']);
$stmt->bindParam(':email', $_POST['email']);
$stmt->bindParam(':email', $_POST['username']);
$stmt->bindParam(':password', password_hash($_POST['password'], PASSWORD_BCRYPT));
to,
$stmt->bindParam(':full_name', $_POST['full_name']);
$stmt->bindParam(':email', $_POST['email']);
$stmt->bindParam(':username', $_POST['username']);
$stmt->bindParam(':password', password_hash($_POST['password'], PASSWORD_BCRYPT));
Now you are actually passing the correct values to the query.
Take note of the following:
Ensure you are validating/sanitizing your user input.
Ensure that you use exit with header to prevent errors.
You are setting the value of $message but not outputting it.
I want to insert some data into a table using PDO. I looked for some examples and I found that I need to use the functions prepare, bind and then execute, however I can not figure out in my code what I am doing wrong because it inserted nothing and I have no error in the query or php code.
if($_POST){
$account = $_POST['account'];
$password = $_POST['password'];
$phone = $_POST['phone'];
$email = $_POST['email'];
$stmt = 'INSERT INTO employer(account, password, phone, email) VALUES(:account, :password, :phone, :email)';
$stmt = $conn->prepare($stmt);
$stmt->bindParam(':account', $account, PDO::PARAM_STR,100);
$stmt->bindParam(':password',$password, PDO::PARAM_STR,100);
$stmt->bindParam(':phone', $phone, PDO::PARAM_STR,100);
$stmt->bindParam(':email', $email, PDO::PARAM_STR,100);
if ($stmt->execute(array('account' => $account,
'password' => $password,
'phone' => $phone,
'email' =>$email
)
)
){
echo "success";
}else{
echo "error";
}
}
Error detected by #jeroen I was binding twice. So I can bind "either bind before the execute statement or send an array as a parameter, not both"
$stmt = $pdo->prepare('
INSERT INTO employer
(account, password, phone, mail)
values (:account, :password, :phone, :mail)');
$stmt->execute(
array(':account' => $account,
':password' => md5($password),
':phone' => $phone,
':mail' => $email
)
);
if ($pdo->lastInsertId())
return true;
else
return false;
I have been learning about making an authentication system more secure. One of the problems with my code is that it is vulnerable to a Time of check to time of use bug. Here is my code:
$stmt = $connection->prepare("SELECT username, password, email FROM users WHERE username=:username");
$stmt->execute(array(':username' => $username));
$rows = $stmt->fetch(PDO::FETCH_ASSOC);
if ($rows != null) {
$_SESSION["message"] = "name already exists";
} else {
$stmt = $connection->prepare("INSERT INTO users(company, username, password, first_name, last_name, address, address2, city, state, zip, phone, email) VALUES (:company, :username, :password, :first_name, :last_name, :address, :address2, :city, :state, :zip, :phone, :email)");
$result = $stmt->execute(array(':company' => $company, ':username' => $username, ':password' => $hashed_password, ':first_name' => $firstName, ':last_name' => $lastName, ':address' => $address1, ':address2' => $address2, ':city' => $city, ':state' => $states, ':zip' => $zip, ':phone' => $phone, ':email' => $email));
if ($result) {
// Success
$_SESSION["message"] = "You've successfully registered.";
redirect_to("login.php");
} else {
// Failure
$_SESSION["message"] = "Registration failed.";
}
}
}
} else {
// This is probably a GET request
}
So, it is first seeing if the user exists and if not, then to go ahead and insert the user's information into the database. But this creates a vulnerability for TOCTTOU. To fix this, I made the 'username' column UNIQUE. Is this the only thing I need to do? Is there a way to combine these two statements so it isn't vulnerable to that type of attack?
I've been reading resources on this and it seems making the column UNIQUE or PRIMARY is the best option. But, I don't want to rely on the database. Any suggestions? Thanks!
Here is my fixed code:
At top of file:
ini_set('display_errors', 'On'); error_reporting(E_ALL);
Then:
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$connection->beginTransaction();
try {
$stmt = $connection->prepare('SELECT 1 FROM users WHERE username = :username LIMIT 1');
$stmt->execute([':username' => $username]);
$check = $stmt->fetchColumn();
if ($check) {
$_SESSION["message"] = "name already exists";
} else {
$stmt = $connection->prepare('INSERT INTO users(company, username, password, first_name, last_name, address, address2, city, state, zip, phone, email) VALUES (:company, :username, :password, :first_name, :last_name, :address, :address2, :city, :state, :zip, :phone, :email)');
$stmt->execute(array(':company' => $company, ':username' => $username, ':password' => $hashed_password, ':first_name' => $firstName, ':last_name' => $lastName, ':address' => $address1, ':address2' => $address2, ':city' => $city, ':state' => $states, ':zip' => $zip, ':phone' => $phone, ':email' => $email)); // this should throw an exception if it fails, no need to check the return value
$_SESSION["message"] = "You've successfully registered.";
}
$connection->commit();
redirect_to("login.php");
} catch (PDOException $e) {
$connection->rollBack();
throw $e;
}
I would maintain the unique constraint on your table as that makes sense from a data perspective.
For your PHP code, simply use transactions. For example...
// make sure you have $connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)
$connection->beginTransaction();
try {
$stmt = $connection->prepare('SELECT 1 FROM users WHERE username = :username LIMIT 1');
$stmt->execute([':username' => $username]);
$check = $stmt->fetchColumn();
if ($check) {
$_SESSION["message"] = "name already exists";
} else {
$stmt = $connection->prepare('INSERT INTO ...');
$stmt->execute([...]); // this should throw an exception if it fails, no need to check the return value
$_SESSION["message"] = "You've successfully registered.";
}
$connection->commit();
redirect_to("login.php");
} catch (PDOException $e) {
$connection->rollBack();
throw $e;
}
hi i have a table in mysql have six fields
ID, mobileNumber, firstName, lastName, email, password , rollID
ID is autoincrement and i want to insert to it using php
php code
public function run($firstName, $lastName, $mobileNumber, $email, $password, $rePassword) {
if (!$this->db->isExistedMobile($mobileNumber)) {
try {
$query = "INSERT INTO user (firstName, lastName, mobileNumber, email, password, rollID)
VALUES (:firstName, :lastName, :mobileNumber, :email, :password, 'rollID')";
$sth = $this->db->prepare($query);
$sth->execute(array(
':firstName' => $firstName,
':lastName' => $lastName,
':mobileNumber' => $mobileNumber,
':email' => $email,
':password' => $password,
':rollID' => "roma"
));
header("location: " . URL . "index");
} catch (PDOException $e) {
die($e->getMessage());
exit;
}
} else {
include 'controlers/Error.php';
$error = new Error();
$error->index("you enterd a used mobile number");
}
}
i have this exception
SQLSTATE[HY093]: Invalid parameter number: number of bound variables does not match number of tokens
the function isExistedMobile always return false so don't worry about it , i don't know where is the wrong , is it in the syntax ? or in the rollID cos i make it static ?
thank you for helping :)
The problem (with your original code) was that the parameter array had a trailing comma, which created an additional null element within it.
I'd recommend reverting to that version (with the literal value for rollID) as originally intended, but make sure you remove the trailing comma after $password:
public function run($firstName, $lastName, $mobileNumber, $email, $password, $rePassword) {
if (!$this->db->isExistedMobile($mobileNumber)) {
$query = "INSERT INTO user (firstName, lastName, mobileNumber, email, password, rollID)
VALUES (:firstName, :lastName, :mobileNumber, :email, :password, 'ddd')";
$sth = $this->db->prepare($query);
$sth->execute(array(
':firstName' => $firstName,
':lastName' => $lastName,
':mobileNumber' => $mobileNumber,
':email' => $email,
':password' => $password // , removed from here
));
header("location: " . URL . "index");
} else {
include 'controlers/Error.php';
$error = new Error();
$error->index("you enterd a used mobile number");
}
}