This is a code that I designed to check if username matches with the email in the database.
If not check the username. if it does not exist, check the email. If it does not exist, create a new username.
The problem is that the query runs and insert a new user every time!! What am I doing wrong??
$word = $_POST['word'];
$explination = $_POST['explination'];
$lhgat = $_POST['lhgat'];
$email = $_POST['email'];
$username = $_POST['username'];
$letterar = idar($_POST['word']);
$letteren = iden($_POST['word']);
if (!empty($word) && !empty($explination) && !empty($lhgat) && !empty($email) && !empty($username) && !empty($letterar) && !empty($letteren)) {
//checking for username and email match
$checkingforuserstmt = $conn->prepare('SELECT id FROM user WHERE username = username AND email = email');
$checkingforuserstmt->execute(array(':username' => $username, ':email' => $email));
$checkingforuserrow = $checkingforuserstmt->fetch(PDO::FETCH_ASSOC);
if($checkingforuserstmt->rowCount() < 0){
//check for username only
$checkingforuserstmt2 = $conn->prepare('SELECT id FROM user WHERE username = username');
$checkingforuserstmt2->execute(array(':username' => $username));
$checkingforuserrow2 = $checkingforuserstmt2->fetch(PDO::FETCH_ASSOC);
if($checkingforuserrow2->rowCount() < 0){
//check for email only
$checkingforuserstmt3 = $conn->prepare('SELECT id FROM user WHERE email = email');
$checkingforuserstmt3->execute(array(':email' => $email));
$checkingforuserrow3 = $checkingforuserstmt3->fetch(PDO::FETCH_ASSOC);
if($checkingforuserrow3->rowCount() < 0){
$insertuser = $conn->prepare("INSERT INTO user VALUES('',:username,:email)");
$insertuser->execute(array(':username' => $username,':email' => $email)); }}}
You need to use the : in the statement, not the binding. for example: select * from table where field = :field not field = field
Otherwise you're just saying the column, not a value.
Related
I have an updating form to update the users information. Here, I have the password input. And I want to, if left blank, not update the password in the database but to leave the one already set up.
For this I have:
$user_password = inputCleaner($_POST['user_password']);
$user_password_repeat = inputCleaner($_POST['user_password_repeat']);
// IF filled, check if both match
if (!empty($user_password) && $user_password != $user_password_repeat) {
$errors .= "Passwords are not the same." . '<br>';
} elseif (!empty($user_password) && $user_password == $user_password_repeat) {
$user_password = hash('sha512', $user_password);
}
// IF NOT FILLED, leave NULL
elseif (empty($user_password)) {
$user_password = '';
}
If all is good, we run the script:
if(!$errors) {
$statement = $connection -> prepare("
UPDATE users SET
user_nickname = :user_nickname,
user_password = COALESCE(NULLIF(:user_password, ''),user_password)
user_pass
user_name = :user_name,
user_last_name = :user_last_name,
user_email = :user_email,
user_picture = :user_picture,
role = :role
WHERE
user_id = :user_id
");
$statement -> execute(array(
':user_nickname' => $user_nickname,
':user_password' => $user_password,
':user_name' => $user_name,
':user_last_name' => $user_last_name,
':user_email' => $user_email,
':user_picture' => $user_picture,
':role' => $role,
':user_id' => $user_id
));
Note my inputCleaner() function is a simple:
function inputCleaner($input) {
$input = trim($input);
$input = stripslashes($input);
$input = htmlspecialchars($input);
return $input;
}
With this, the password is not updated at all, it won´t change it.
Instead of converting '' to NULL and then using COALESCE(), you can simply compare :user_password to ''.
You also had some syntax errors: a missing comma after assigning to user_password and an extra line with user_pass after that.
$statement = $connection -> prepare("
UPDATE users SET
user_nickname = :user_nickname,
user_password = IF(:user_password = '',user_password, :user_password),
user_name = :user_name,
user_last_name = :user_last_name,
user_email = :user_email,
user_picture = :user_picture,
role = :role
WHERE
user_id = :user_id
");```
I am trying to create a signup page and need to validate if username and email already exit.
If I do it in two queries, it works fine, but switch to one query, then it doesn't work properly, it doesn't validate one of value sometimes.
I tried as following but its not working properly, sometimes it doesn't validate for email or username:
$uname = $_POST['username'];
$email = $_POST['email'];
$sql = "SELECT uid FROM users WHERE username = :username OR email = :email";
$stmt1 = $pdo->prepare($sql);
$stmt1->bindParam(":username", $uname, PDO::PARAM_STR);
$stmt1->bindParam(":email", $email, PDO::PARAM_STR);
$stmt1->execute();
if($stmt1->rowCount() == 1){
$rows = $stmt1->fetch();
if($rows['username'] == 1){
$errors['username'] = "Username already in use.";
}else{
$username = $uname;
}
if($rows['email'] == 1){
$errors['email'] = "Email already in use.";
}else{
$email= $email;
}
}
unset($stmt1);
rowCount method returns >= 1 records when username or email match. Try that code:
$username = $_POST['username'];
$email = $_POST['email'];
$errors = array();
$sql = "SELECT username, email FROM users WHERE username = :username OR email = :email";
$stmt1 = $pdo->prepare($sql);
$stmt1->bindParam(":username", $username, PDO::PARAM_STR);
$stmt1->bindParam(":email", $email, PDO::PARAM_STR);
$stmt1->execute();
if($stmt1->rowCount() > 0){
$rows = $stmt1->fetchAll();
foreach($rows as $row) {
if($row['username'] === $username) {
$errors['username'] = "Username already in use.";
}
if($row['email'] === $email) {
$errors['email'] = "Email already in use.";
}
}
$stmt1->closeCursor();
}
You Just get count from this query
$sql = "SELECT uid FROM users WHERE username = :username OR email = :email";
instead of
$sql = "SELECT uid,count(uid) FROM users WHERE username = :username OR email = :email";
Hope it will help with single query
I'm implementing a login script which isn't working correctly. I want users to be able to login with either their usernames or emails. I have two tables:
user - contains login information(username, password, email, isactive)
userprofile - contains profile information
ISSUES/ERRORS:
Logging in with the email addresses doesn't work.
If the username alone is entered, leaving the password field empty, the user is still logged in regardless.
THE CODE(isactive checks if a user's account has been activated after email verification)
$uname = htmlspecialchars($_POST['username']);
$pword = htmlspecialchars($_POST['password']);
$isActive = 1;
$getId = 0;
try{
$stmt = $db->prepare("SELECT * FROM user WHERE username = :username OR email = :email AND password = :password AND isactive = :isactive");
$stmt->execute(array(':username' => $uname, ':email' => $uname, ':password' => $pword, ':isactive' => $isActive));
$numrows = $stmt->fetch(PDO::FETCH_ASSOC);
//to enable me count number of rows returned
$number = $stmt->fetch(PDO::FETCH_NUM);
$_SESSION['username'] = $numrows['username'];
$getId = $numrows['Id'];//get the id of the user
}catch(PDOException $ex){
echo 'QUERY ERROR: ' . $ex->getMessage();
}
/*this checks to see that the user has a profile (userId is a foreign key, thus user.Id = userprofile.userId always)*/
try{
$query = $db->prepare("SELECT * from userprofile WHERE userId = :userId");
$query->execute(array(':userId' => $getId));
$row = $query->fetchAll();
}catch(PDOException $exc){
echo 'QUERY ERROR: ' . $exc->getMessage();
}
//Check results and log user in
if(count($number) == 1 && count($row) == 1){
header("Location: index.php");
}
else {$errorMessage = "<p style='color:#ff851b'>Invalid username or password</p>";}
What do i need to modify to get this working? Thanks
You can easily include the row count in your query as well:
And adjust the query :
SELECT *, count(*) AS numrows
FROM user
WHERE (username = :username OR email = :email) AND
password = :password AND isactive = :isactive
Please make the following changes:
$stmt->execute(array(':username' => $uname,
':email' => $uname,
':password' => $pword,
':isactive' => $isActive));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if(!$row){
throw new Exception('User not found');
}
//get user data
$numrows = (int)$row['numrows'];
if($numrows === 1){
//found a user
$_SESSION['username'] = $row['username'];
$id = $row['Id'];
}
The main issue I see is this one; some brackets are needed:
Before:
$stmt = $db->prepare("SELECT * FROM user WHERE username = :username OR email = :email AND password = :password AND isactive = :isactive");
After:
$stmt = $db->prepare("SELECT * FROM user WHERE ((username = :username AND password = :password) OR (email = :email AND password = :password)) AND isactive = :isactive");
Also, in this line you are assigning $uname to username and email - possible copy/paste error here as well?
$stmt->execute(array(':username' => $uname, ':email' => $uname, ':password' => $pword, ':isactive' => $isActive));
Try
SELECT * FROM user WHERE (username = :username OR email = :email) AND password = :password AND isactive = :isactive"
as query... Should work...
Hi my test website wont save any kind of data in the database so when i register it wont save it to the database so i cant login. can someone explain what is wrong with the code and tell me how to fix it thanks!
heres code
Register code:
$reg = #$_POST['reg'];
//declaring variables to prevent errors
$fn = ""; //First Name
$ln = ""; //Last Name
$un = ""; //Username
$em = ""; //Email
$em2 = ""; //Email 2
$pswd = ""; //Password
$pswd2 = ""; // Password 2
$d = ""; // Sign up Date
$u_check = ""; // Check if username exists
//registration form
$fn = strip_tags(#$_POST['fname']);
$ln = strip_tags(#$_POST['lname']);
$un = strip_tags(#$_POST['username']);
$em = strip_tags(#$_POST['email']);
$em2 = strip_tags(#$_POST['email2']);
$pswd = strip_tags(#$_POST['password']);
$pswd2 = strip_tags(#$_POST['password2']);
$d = date("Y-m-d"); // Year - Month - Day
if ($reg) {
if ($em==$em2) {
// Check if user already exists
$u_check = mysql_query("SELECT username FROM users WHERE username='$un'");
// Count the amount of rows where username = $un
$check = mysql_num_rows($u_check);
//Check whether Email already exists in the database
$e_check = mysql_query("SELECT email FROM users WHERE email='$em'");
//Count the number of rows returned
$email_check = mysql_num_rows($e_check);
if ($check == 0) {
if ($email_check == 0) {
//check all of the fields have been filed in
if ($fn&&$ln&&$un&&$em&&$em2&&$pswd&&$pswd2) {
// check that passwords match
if ($pswd==$pswd2) {
// check the maximum length of username/first name/last name does not exceed 25 characters
if (strlen($un)>30||strlen($fn)>30||strlen($ln)>30) {
echo "The maximum limit for username/first name/last name is 30 characters!";
}
else
{
// check the maximum length of password does not exceed 25 characters and is not less than 5 characters
if (strlen($pswd)>30||strlen($pswd)<5) {
echo "Your password must be between 5 and 30 characters long!";
}
else
{
//encrypt password and password 2 using md5 before sending to database
$pswd = md5($pswd);
$pswd2 = md5($pswd2);
$query = mysql_query("INSERT INTO users VALUES ('','$un','$fn','$ln','$em','$pswd','$d','0','Write something about yourself.','','','no')");
die("<h2>Welcome to test</h2>Login to your account to get started");
}
}
}
else {
echo "Your passwords don't match!";
}
}
else
{
echo "Please fill in all of the fields";
}
}
else
{
echo "Sorry, but it looks like someone has already used that email!";
}
}
else
{
echo "Username already taken ...";
}
}
else {
echo "Your E-mails don't match!";
}
}
connect code
<?php
mysql_connect("localhost","root","") or die ("Cant Connect To DataBase!");
mysql_select_db("test") or die ("Cant Select DataBase");
?>
and the tabel
CREATE TABLE IF NOT EXISTS `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) NOT NULL,
`first_name` varchar(255) NOT NULL,
`last_name` varchar(255) NOT NULL,
`email` varchar(255) NOT NULL,
`password` varchar(32) NOT NULL,
`sign_up_date` date NOT NULL,
`activated` enum('0','1') NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
<?php
// CHECK IF THE FORM HAS BEEN SUBMITTED
if (isset($_POST['REG'])) {
/* these are the columns to be filled
username
first_name
last_name
email
password
sign_up_date
activated
*/
// GATHER VARIABLES, as we are sure the form has been requested via $_POST there is no need to 'declare' variables
$first_name = trim($_POST['first_name']);
$last_name = trim($_POST['last_name']);
$username = trim($_POST['username']);
// JUST USING ONE EMAIL VARIABLE, BOTH EMAILS BEING THE SAME SHOULD BE CLIENT-VALIDATED
$email = trim($_POST['email']);
// THE SAME AS ABOVE WITH PASS
$password = trim($_POST['password']);
$date = trim($_POST['date']);
$acive = trim($_POST['acive']);
// THIS FUNCTION TESTS FOR EMPTY STRINGS, SELECTS SET TO 0 AND EMPTY ARRAYS
function test_valid() {
$args = func_get_args();
foreach ($args as $value) {
if ($value === 0 || $value == '' || empty($value)) {
return false;
} else {
$foo = true;
}
}
return $foo;
}
// MAKE THE TEST
if (test_valid($first_name, $last_name, $username, $email)) {
// CONTINUE TO THE DATABASE
// CONNECT TO THE DATABASE USING PDO
$conn = new PDO('mysql:host=YOURHOST;dbname=YOURDBNAME', 'YOURUSER', 'YOURPASS');
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// PREPARE THE STATEMENT TO CHECK THE VALUES IN THE DATABASE
$stmt = $conn->prepare("SELECT id, username, email FROM users WHERE username = :username OR email = :email ORDER BY id DESC LIMIT 1");
// BIND THE PARAMETERS TO THE :thingy's
$stmt->bindParam(':username', $username, PDO::PARAM_STR);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
$stmt->execute();
//get an array containing arrays<- these ones being the rows of the query
$result = $stmt->fetchAll();
if (empty($result)) {
$password = crypt($password, $username);
$stmt = $conn->prepare("INSERT INTO users VALUES ('', :username , :first_name , :last_name , :email , :password , NOW(), 0)");
$stmt->bindParam(':username', $username, PDO::PARAM_STR);
$stmt->bindParam(':first_name', $first_name, PDO::PARAM_STR);
$stmt->bindParam(':last_name', $last_name, PDO::PARAM_STR);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
$stmt->bindParam(':password', $password, PDO::PARAM_STR);
$stmt->execute();
} else {
//there were matching rows, therefore the username or the e-mail were already registered
}
} else {
//there were invalid parameters in the form
}
} else {
// form was not submitted
}
?>
You should describe in more detail what you are trying to achieve, this may not be the perfect answer/solution/code, but it's a cleaner one and uses PDO'S bindParam to avoid SQL injections and PHP's crypt(), better than mdf5 See the post in thecodinglove
Also, a good place to start learning (I've used it) is Tutsplus with Jeffrey Way, the best beginner's PHP-MySQL tutorial I've seen.
It would also help to see what errors is throwing php with E_ALL
Hope this helps you in your test.
I'm new to PDO PHP (just started today). I am attempting too write a login function, but it is returning false, even though i know the credentials are correct.
I think is is the attempt to get the amount of rows which is tripping the script up, can you help?
function check_login($email, $username, $password)
{
$host = 'localhost';
$port = 3306;
$database = 'example';
$username = 'root';
$password = '';
$dsn = "mysql:host=$host;port=$port;dbname=$database";
$db = new PDO($dsn, $username, $password);
$password = md5($password);
$statement = $db->prepare("SELECT * FROM users WHERE email = ? or username = ? and password = ?");
$statement->execute(array($email, $username, $password));
while ($result = $statement->fetchObject()) {
$sql = "SELECT count(*) FROM users WHERE email = ? or username = ? and password = ?";
$result1 = $db->prepare($sql);
$result1->execute(array($email, $username, $password));
$number_of_rows = $result1->fetchColumn();
if ($number_of_rows == 1)
{
$_SESSION['login'] = true;
$_SESSION['uid'] = $result->uid;
return TRUE;
}
else
{
return FALSE;
}
}
}
This:
WHERE email = ? or username = ? and password = ?
... equals this:
WHERE email = ? or (username = ? and password = ?)
... due to operator precedence. That means that if you validate with an e-mail address, you are not required to provide a valid password to log in.
Once you've found out whether the user exists, you make a second query to count the number of matching users. The database table should not be able to hold duplicate users in the first place! Columns username and email should be defined as unique indexes.
There's no point in using a while loop if it's going to return in the first iteration. It may work, but it's confusing.
This should be enough:
$statement = $db->prepare('SELECT uid FROM users WHERE (email = ? or username = ?) and password = ?');
$statement->execute(array($email, $username, $password));
if ($result = $statement->fetchObject()) {
$_SESSION['login'] = true;
$_SESSION['uid'] = $result->uid;
return TRUE;
}else{
return FALSE;
}
Edit: BTW, you should not be storing passwords in plain text. Countless sites have been hacked and their passwords stolen. Google for salted passwords.