PHP Error: number of bound variables does not match number of tokens.
What am i missing here? I'm trying to add a new user for my med application.
public function register($uname,$umail,$upass,$fname,$llastname)
{
try
{
$new_password = password_hash($upass, PASSWORD_DEFAULT);
$stmt = $this->conn->prepare("INSERT INTO users(name, lastname, user_name, user_email, user_pass) VALUES(:fname, :llastname, :uname, :umail, :upass)");
$stmt->bindparam(":fname", $fname);
$stmt->bindparam(":llastname", $llastname);
$stmt->bindparam(":uname", $uname);
$stmt->bindparam(":umail", $umail);
$stmt->bindparam(":upass", $new_password);
$stmt->execute();
return $stmt;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function doLogin($uname,$umail,$upass)
{
try
{
$stmt = $this->conn->prepare("SELECT name, lastname, user_id, user_name, user_email, user_pass FROM users WHERE name=:fname, lastname=:llastname, user_name=:uname OR user_email=:umail ");
$stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() == 1)
{
if(password_verify($upass, $userRow['user_pass']))
{
$_SESSION['user_session'] = $userRow['user_id'];
return true;
}
else
{
return false;
}
}
}
catch(PDOException $e)
{
//HTTPS
echo $e->getMessage();
}
}
addUser.php did i bind it correctly ?
$uname = strip_tags($_POST['txt_uname']);
$umail = strip_tags($_POST['txt_umail']);
$upass = strip_tags($_POST['txt_upass']);
$fname = strip_tags($_POST['txt_fname']);
$llastname = strip_tags($_POST['txt_llastname']);
Here:
$stmt = $user->runQuery("SELECT name, lastname, user_name,user_email
FROM users
WHERE name=:fname,
lastname=:llastname,
user_name=:uname
OR user_email=:umail");
You use 4 (four!) parameters: :fname, :llastname, :uname, :umail
Then, while executing it you ONLY bind 2 (two) parameters:
$stmt->execute(array(':uname' => $uname, ':umail' => $umail));
This is exactly why you're getting that error.
Any by the way, your SQL query is errored. Instead of , (comma) you should use AND to join the WHERE conditions. Like this:
$stmt = $user->runQuery("SELECT name, lastname, user_name,user_email
FROM users
WHERE name=:fname
AND lastname=:llastname
AND user_name=:uname
OR user_email=:umail");
Although, I am not entirely sure about ANDs and ORs there, you may need to use parantheses to achieve the logic you need
Related
This question already has answers here:
Reference - What does this error mean in PHP?
(38 answers)
Closed 2 years ago.
This is the login.php,
with the local host my web site is working properly. However, on server it is not working.
The web site is conecting with DB and checking the user, email, password, but the session is not starting.
I have checked already the PHP version from both, localhost and server. They are the same version php 7.4.
I have no Idea how to fix this problem, if you know how to fix it, I have already paid some people with more experience to fix it. but they didn't fix. so if you can help me to solve it please contact me and we can negotiate it.
thanks all
require_once 'php/dbconfig.php';
class USER
{
private $conn;
public function __construct()
{
$database = new Database();
$db = $database->dbConnection();
$this->conn = $db;
}
public function runQuery($sql)
{
$stmt = $this->conn->prepare($sql);
return $stmt;
}
public function register($fname, $mname, $lname, $uname, $dob, $pnumber, $streetname, $number, $city, $state, $postcode, $country, $umail, $upass, $usertype )
{
try
{
$new_password = password_hash($upass, PASSWORD_DEFAULT);
$stmt = $this->conn->prepare("INSERT INTO customers(FName,MName, LName, UserName, DOB, PNumber, StreetName, Number, City, State, PostCode, Country, Email, Password, UserType)
VALUES(:fname, :mname, :lname, :uname, :dob, :pnumber, :streetname, :number, :city, :state, :postcode, :country, :umail, :upass, :usertype)");
$stmt->bindparam(":fname", $fname);
$stmt->bindparam(":mname", $mname);
$stmt->bindparam(":lname", $lname);
$stmt->bindparam(":uname", $uname);
$stmt->bindparam(":dob", $dob);
$stmt->bindparam(":pnumber", $pnumber);
$stmt->bindparam(":streetname", $streetname);
$stmt->bindparam(":number", $number);
$stmt->bindparam(":city", $city);
$stmt->bindparam(":state", $state);
$stmt->bindparam(":postcode", $postcode);
$stmt->bindparam(":country", $country);
$stmt->bindparam(":umail", $umail);
$stmt->bindparam(":upass", $new_password);
$stmt->bindparam(":usertype", $usertype);
$stmt->execute();
return $stmt;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function doLogin($uname,$umail,$upass)
{
try
{
$stmt = $this->conn->prepare("SELECT CustomerID, UserType, UserName, FName, LName, Email, Password FROM customers WHERE UserName=:uname OR Email=:umail");
$stmt->execute(array(':uname'=>$uname, ':umail'=>$umail,));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() == 1)
{
if(password_verify($upass, $userRow['Password']))
{
$_SESSION['user_session'] = $userRow['CustomerID'];
$_SESSION['user_name']= $userRow['UserName'];
$_SESSION['user_fname']= $userRow['FName'];
$_SESSION['user_lname']= $userRow['LName'];
$_SESSION['user_usertype']= $userRow['UserType'];
return true;
}
else
{
return false;
}
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
public function is_loggedin()
{
if(isset($_SESSION['user_session']))
{
return true;
}
}
public function redirect($url)
{
header("Location: $url");
}
public function doLogout()
{
session_destroy();
unset($_SESSION['user_session']);
return true;
}
}
?>
Add session_start(); start of the page.
<?php
session_start(); //add this line
require_once 'php/dbconfig.php';
This question already has answers here:
Row count with PDO
(21 answers)
Closed 4 years ago.
I cannot figure this out, I've been reading numerous Stack overflow threads and I keep getting an issue,
right now if the user types anything, regardless if it is the same username or email, it would come up with an error. Please help!
I want the error message to appear when the user types an username or email that is already on the database.
$sql = "SELECT count(*) FROM users WHERE user_email = :email OR user_name = :username";
$query1 = $DBH->prepare($sql);
$query1->execute(array(':username' => $username,':email' => $email));
if ($query1->rowCount() > 0){
// User Exists
$error = "Username or E-Mail in Use";
} else{
// User Does Not Exist
//No errors - let’s create the account
//Encrypt the password with a salt
$encryptedPass = password_hash($_POST['password'], PASSWORD_DEFAULT);
//Insert DB
$query = "INSERT INTO users (user_email, user_password, user_forename, user_lastname, user_name, user_gender, user_country, user_number) VALUES (:email, :password, :firstname, :lastname, :username, :gender, :country, :mobile)";
$result = $DBH->prepare($query);
$result->bindParam(':username', $_POST['username']);
$result->bindParam(':firstname', $_POST['firstname']);
$result->bindParam(':lastname', $_POST['lastname']);
$result->bindParam(':email', $_POST['email']);
$result->bindParam(':gender', $_POST['gender']);
$result->bindParam(':country', $_POST['country']);
$result->bindParam(':mobile', $_POST['mobile']);
$result->bindParam(':password', $encryptedPass);
if($result->execute()){
echo '<div class="alert alert-success" role="alert">Registration Successful!</div>';
echo "<script> window.location.assign('index.php?p=login'); </script>";
}
}
EDIT
$stmt = $DBH->prepare("SELECT COUNT(*) FROM users WHERE user_email = :email OR user_name = :username");
$stmt->execute(array(':username' => $username,':email' => $email));
$count = $stmt->fetchColumn();
var_dump($count);
if ($count > 0) {
$error1 = "Username or E-Mail in Use. Please try another.";
}
if(!$error){
//No errors - let’s create the account
//Encrypt the password with a salt
$encryptedPass = password_hash($_POST['password'], PASSWORD_DEFAULT);
//Insert DB
$query = "INSERT INTO users (user_email, user_password, user_forename, user_lastname, user_name, user_gender, user_country, user_number) VALUES (:email, :password, :firstname, :lastname, :username, :gender, :country, :mobile)";
$result = $DBH->prepare($query);
$result->bindParam(':username', $_POST['username']);
$result->bindParam(':firstname', $_POST['firstname']);
$result->bindParam(':lastname', $_POST['lastname']);
$result->bindParam(':email', $_POST['email']);
$result->bindParam(':gender', $_POST['gender']);
$result->bindParam(':country', $_POST['country']);
$result->bindParam(':mobile', $_POST['mobile']);
$result->bindParam(':password', $encryptedPass);
if($result->execute()){
echo '<div class="alert alert-success" role="alert">Registration Successful!</div>';
// echo "<script> window.location.assign('index.php?p=login'); </script>";
}
}
var dump = string(1) "0"
A few ways to go about this. As #chris85 mentioned you need to actually fetch the result instead of using rowCount().
Edit: Removed the first example.
<?php
$stmt = $pdo->prepare("SELECT COUNT(*) FROM users WHERE user_email = :email OR user_name = :username");
$stmt->execute(array(':username' => $username,':email' => $email));
$count = $stmt->fetchColumn();
if ($count > 0) {
$error = "Username or E-Mail in Use";
} else {
...
So I have two functions for registering and logging in. Registering works fine, the user table is populated, the hash is stored in the user_pass column etc. When logging in, I keep getting the "Wrong Details" error message. It seems the password_verify isn't matching the hash with the inputted password. Can you guys see anything wrong with my code? I'm scratching my head here....
public function register($uname,$umail,$upass)
{
try
{
$new_password = password_hash($upass, PASSWORD_DEFAULT);
$stmt = $this->conn->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();
}
}
public function doLogin($uname,$umail,$upass)
{
try
{
$stmt = $this->conn->prepare("SELECT user_id, user_name, user_email, user_pass FROM users WHERE user_name=:uname OR user_email=:umail ");
$stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if($stmt->rowCount() == 1)
{
if(password_verify($upass, $userRow['user_pass']))
{
$_SESSION['user_session'] = $userRow['user_id'];
return true;
}
else
{
return false;
}
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
rowCount() does not return the number of rows in a SELECT statement. There is no need to test to see if the query succeeded, you can move right to testing the password:
public function doLogin($uname,$umail,$upass)
{
try
{
$stmt = $this->conn->prepare("SELECT user_id, user_name, user_email, user_pass FROM users WHERE user_name=:uname OR user_email=:umail ");
$stmt->execute(array(':uname'=>$uname, ':umail'=>$umail));
$userRow=$stmt->fetch(PDO::FETCH_ASSOC);
if(password_verify($upass, $userRow['user_pass']))
{
$_SESSION['user_session'] = $userRow['user_id'];
return true;
}
else
{
return false;
}
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
I have two tables login and users. in table login i have user_id(primary key), username(varchar),password(varchar) and in table users id(primary key),username(varchar),user_id(int)..what i want to happen is that when i insert a record in table login the user_id should be inserted also in user_id in table users..please help me with it..
Here's my code for insertion
public function create($username,$password,$province)
{
try
{
$stmt = $this->db->prepare("INSERT INTO login(username,password,province) VALUES(:username, :password, :province)");
$stmt->bindparam(":username",$username);
$stmt->bindparam(":password",$password);
$stmt->bindparam(":province",$province);
$stmt->execute();
$stmt = $this->db->prepare("INSERT INTO sample(username) VALUES (:username)");
$stmt->bindparam(":username",$username);
$stmt->execute();
return true;
}
catch(PDOException $e)
{
echo $e->getMessage();
return false;
}
}
As of now what i done is inserting a record into tables at the same time..but i'm kinda struggling on how to insert the user_id from table login to user_id in table users..
You should be able to use PDO::lastInsertId -> $this->db->lastInsertId();
public function create($username,$password,$province)
{
try
{
$stmt = $this->db->prepare("INSERT INTO login(username,password,province) VALUES(:username, :password, :province)");
$stmt->bindparam(":username",$username);
$stmt->bindparam(":password",$password);
$stmt->bindparam(":province",$province);
$stmt->execute();
$user_id = $this->db->lastInsertId();
$stmt = $this->db->prepare("INSERT INTO sample(username,user_id) VALUES (:username, :user_id)");
$stmt->bindparam(":user_id",$user_id);
$stmt->bindparam(":username",$username);
$stmt->execute();
return true;
}
catch(PDOException $e)
{
echo $e->getMessage();
return false;
}
}
Alternatively you could do a INSERT ... SELECT ... query,
which would look like -
INSERT INTO sample(username,user_id) SELECT :username, user_id FROM login WHERE username = :username1
so your function would look like -
public function create($username,$password,$province)
{
try
{
$stmt = $this->db->prepare("INSERT INTO login(username,password,province) VALUES(:username, :password, :province)");
$stmt->bindparam(":username",$username);
$stmt->bindparam(":password",$password);
$stmt->bindparam(":province",$province);
$stmt->execute();
$stmt = $this->db->prepare("INSERT INTO sample(username,user_id) SELECT :username, user_id FROM login WHERE username = :username1");
$stmt->bindparam(":username",$username);
$stmt->bindparam(":username1",$username);
$stmt->execute();
return true;
}
catch(PDOException $e)
{
echo $e->getMessage();
return false;
}
}
You can create database trigger like
Create or replace trigger <trigger_name> after insert login ...
In which you on insert of first table you can insert record in another table with same id. You can create trigger as specified
Here
You haven't defined $user_id
make changes to the function like this
public function create($username,$password,$province)
{
try
{
$stmt = $this->db->prepare("INSERT INTO login(username,password,province) VALUES(:username, :password, :province)");
$stmt->bindparam(":username",$username);
$stmt->bindparam(":password",$password);
$stmt->bindparam(":province",$province);
$stmt->execute();
// make changes here create $user_id
$user_id = $this->db->insert_id;
$stmt = $this->db->prepare("INSERT INTO sample(username,user_id) VALUES (:username, :user_id)");
// make changes here in user_id instead of user_i
$stmt->bindparam(":user_id",$user_id);
$stmt->bindparam(":username",$username);
$stmt->execute();
return true;
}
catch(PDOException $e)
{
echo $e->getMessage();
return false;
}
}
I'm trying to create a login system using Slim Jquery and Ajax. I've got the log in part working with minimal issues, now I just need to be able to hash the password. I know I can use md5, sha1 and/or salt to hash but I know that it is recommenced that password_hash is used instead. I know how to hash with any of the other 3 I mentioned because while using bindParam you can just place it around the variable. My question is, how do I use password_hash with bindParam. The closest answer I found on this site didn't do much to help.
My current code is:
$app->post('/addUser/', 'addUser');
function addUser()
{
$request = \Slim\Slim::getInstance()->request();
$q = json_decode($request->getBody());
$sql = "INSERT INTO users(firstName, lastName, userName, password) VALUES (:firstName, :lastName, :userName, :password)";
try{
$dbConnection();
$stmt=$db->prepare($sql);
$stmt->bindParam("firstName", $q->firstName);
$stmt->bindParam("lastName", $q->lastName);
$stmt->bindParam("userName", $q->userName);
$stmt->bindParam("password", $q->password);
$stmt->execute();
$db=null;
}
catch(PDOException $e){
echo $e->getMessage();
}
}
Verify Code:
$app->post('/logIn/', 'lonIn');
function logIn()
{
$request = \Slim\Slim::getInstance()->request();
$q = json_decode($request->getBody());
$sql = "SELECT * FROM users WHERE userName=:userName";
try{
$db = getConnection();
$stmt=$db->prepare($sql);
$stmt->bindParam("userName", $q->userName);
$execute = $stmt->execute();
$db = null;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
if($execute == true)
{
$array = $stmt->fetch(PDO::FETCH_ASSOC);
$hashedPassword = $array['password'];
if(password_verify($q->password), $hashedPassword))
{
echo 'Valid';
}
else
{
echo 'Invalid';
}
}
}
Any help would be appreciated.
To encrypt password you need to create a new variable $hashedPassword which you will store in the db for each user. When verifying the user you will select a user from the db passing their username and using password_verify($passToBeVerified,$ourHashedpasswordfromDb) this will return a boolean.
$app->post('/addUser/', 'addUser');
function addUser() {
$request = \Slim\Slim::getInstance()->request();
$q = json_decode($request->getBody());
$hashedPassword = password_hash($q->password, PASSWORD_BCRYPT);
$sql = "INSERT INTO users(firstName, lastName, userName, password) VALUES (:firstName, :lastName, :userName, :password)";
try {
$dbConnection();
$stmt = $db->prepare($sql);
$stmt->bindParam(":firstName", $q->firstName);
$stmt->bindParam(":lastName", $q->lastName);
$stmt->bindParam(":userName", $q->userName);
$stmt->bindParam(":password", $hashedPassword);
$execute = $stmt->execute();
if ($execute == true) {
$verifyUser = verifyUser($q->password, $q->userName);
if ($verifyUser == TRUE) {
echo 'valid Username and Password';
} else {
echo 'Invalid Username and password';
}
}
$db = null;
} catch (PDOException $e) {
echo $e->getMessage();
}
}
function verifyUser($passWordToVerify, $userNameToVerify) {
// $request = \Slim\Slim::getInstance()->request();
// $q = json_decode($request->getBody());
//Select a user data according to their username
$sql = "select firstName, lastName, userName, password from users where userName = :userName";
try {
$dbConnection();
$stmt = $db->prepare($sql);
$stmt->bindParam(":userName", $userNameToVerify);
$execute = $stmt->execute();
$db = null;
} catch (PDOException $e) {
echo $e->getMessage();
}
if ($execute == True) {
/*
* if the query executes and returs the user saved user details lets now compare
* the password from the db and the password that the user has entered
*/
$array = $stmt->fetch(PDO::FETCH_ASSOC);
$hashedPassword = $array['password'];
if (password_verify($passWordToVerify, $hashedPassword)) {
echo 'Password is valid!';
return true;
} else {
echo 'Invalid password.';
return false;
}
}
}