I want to check if username and email taken in my registration script.
This is how I check with query:
$emailcheck = "SELECT COUNT(email) AS nume FROM members WHERE email = :email";
//bindValue
//execute
//fetch
if($rowe['nume'] > 0){
$errors[] = "E-mail exist.";
}
And also I'm doing the same thing for username;
$usercheck = "SELECT COUNT(username) AS numu FROM members WHERE username = :username";
//bindValue
//execute
//fetch
if($rowu['numu'] > 0){
$errors[] = "Username taken.";
}
*
I want to go one step further and handle all of stuff with one query.
But I couldn't came up with such query.
I tried:
$check = "SELECT COUNT(username) AS numu and COUNT(email) AS nume FROM members WHERE username = :username OR email = :email";
but probably It's ridiculous.
How to handle what I want with one query?
And after I want to check like that:
if($row['numu'] > 0){
$errors[] = "Username taken.";
}
if($rowe['nume'] > 0){
$errors[] = "E-mail exist.";
}
So it will be less code, instead of connecting same table twice and bindValue, execute, fetch for second time.
You can just do Union All to unite those queries:
SELECT COUNT(email) AS num FROM members WHERE email = :email
UNION ALL
SELECT COUNT(username) AS num FROM members WHERE username = :username
Then extract 2 according rows.
OR, MySQL allows this thing:
SELECT
(SELECT COUNT(email) FROM members WHERE email = :email) as nume,
(SELECT COUNT(username) FROM members WHERE username = :username) as numu
if you want 1 rows with 2 columns.
Do that only if you need to see which one is already present. Otherwise just do this:
SELECT 1 FROM members WHERE email = :email OR username = :username LIMIT 1
Yes, consider not doing count() because you don't need to count all the rows. You just need to stop if you find just one. So either do a LIMIT or IF EXISTS()
I don't think you really need to count. Assuming you want to check if either username or email already exist because they are required to be unique on your user table, you can do this:
First, add a unique index to each of those columns in your database. You may already have this, but if you want those values to be unique, this will ensure that even if your PHP code fails to do so for some reason.
Then you can use this query:
SELECT username, email FROM members WHERE username = :username OR email = :email
This will return either zero, one, or two rows, where:
0 = neither username nor email was found
1 = one row was found having either username, email, or both
2 = username was found in one row and email was found in another
Then you can loop over your results, comparing them to the user input, and set your errors.
while ($row = //fetch) {
if ($row['username'] == $username) {
$errors[] = "Username taken.";
}
if ($row['email'] == $email) {
$errors[] = "E-mail exist.";
}
}
You can try this after removing and between count
$check = "SELECT COUNT(username) AS uname ,
COUNT(email) AS uemail FROM members
WHERE (username = :username OR email = :email)";
Related
I am trying to query two different tables just, to see if there is one match. I have done a lot of research on how to do this and all I keep seeing is using the join clause. But I am not looking for a match between two tables. I just need to query both tables and see if there is one row with a match.
This is the code I'm using.
$query = " SELECT id,account_type,email, password FROM client
WHERE email = ?
UNION
SELECT id,account_type,email, password FROM freelancers
WHERE email = ? ";
$email = $this->input->post("email");
$result = $this->db->query($query, [$email]);
// Just check if first there is an email that exists the database
if($result -> num_rows() == 1) {
//Do something
}
You could try using a subquery:
$query = "SELECT * FROM client WHERE email = (SELECT email FROM freelancers WHERE email = ?)";
$email = $this->input->post("email");
$result = $this->db->query($query, array($email));
I have database with 2 table. Students and Profesors. I create one more login table and there are all email and passwords from students and profesors. I want to create that Student try to login that will send him on some student.php and when profesor try to login it will send him on profesor.php
I try with this code, but it always return me 1. So this is not good options..
if(isset($_POST['Submit'])){
$sql= "SELECT COUNT (*) FROM `students` AND 'Profesors' WHERE `username` = :username and `password` = :password ";
$result = $connection->prepare($sql);
$result->bindParam(":username" ,$_POST['username']);
$result->bindParam(":password" ,$_POST['password']);
$result->execute();
$num=$result->rowCount();
if($num > 0){
header("location:index.php");
}else{
header("location:login.php");
}
I need some idea, how to change my datebase or this login code.
I would personally not let professors and student use the same login. Now to answer the question I would change my query to the following:
SELECT user_type FROM `login_table`
WHERE `username` = :username AND `password` = :password
once query return result I would check the user_type field and redirect accordingly.
$num=$result->rowCount();
if($num > 0){
$data=$result->fetch();
if($data['professor']){
header("location: professor.php");
}else{
header("location: student.php");
}
}else{
header("location:login.php");
}
Here's an idea of how you might want to structure this
Have a table defining types of accounts, maybe
account_type_id | account_type_desc | account_type_dest
Where the first is unique key, the second is "Professor" "Student" or anything else you add, and the third is where you want to send that type of user. "student.php", "professor.php", etc
Then your user table would be something like
account_id | account_type_id | email | password
Then you can query the user table for a user matching the person trying to login in, authenticate their password, grab the account type id and turn it against the table of account types and then you can act based on that information
You can do this using a subquery and union statements. You can create a single table out of the two using a union statement
$subquery = "SELECT username,password FROM `students` UNION SELECT username,password FROM `Profesors`";
Then run a query using the subquery as your source table
$sql= "SELECT * FROM (" . $subquery . ") WHERE `username` = :username and `password` = :password ";
Then use rowCount to determine how many rows were returned.
You want to use php session or issue a cookie to the user for a proper and secure user login.
In your query I think you wanted:
$sql= "SELECT COUNT (*) FROM `students` AND 'Profesors' WHERE `username` = ".$_POST['username']." and `password` = ".$_POST['password']." ";
I have this code here:
$selectUserQuery = 'SELECT user_id, email_address, password FROM user WHERE email_address = :email_address AND password = :password AND confirm_status = 1';
$prepSelectUser = $conn->prepare($selectUserQuery);
$prepSelectUser->bindParam(':email_address', $emailEnc, PDO::PARAM_STR);
$prepSelectUser->bindParam(':password', $passwordEnc, PDO::PARAM_STR);
$prepSelectUser->execute();
$userResult = $prepSelectUser->fetchAll();
$userCount = count($userResult);
I select the email address and password to see if they match (this is for login) and I need the user_id to start a session with the user_id as its value. However, the fetchAll() function returns an array of the results, but I need the user_id separately, only to use it as a value for the session.
How do I fetch the user_id separately?
Try this:
foreach ( $userResult AS $row ) {
var_dump($row[0]);
}
It should be in Userresult::
normaly is hould be:
$userResult[0]['user_id'] (1st user)
$userResult[1]['user_id'] 2th user
$userResult[5]['user_id'] 6th user....
I have written a code to check whether the username exists in the database or not. It seems to return that there is no such username exists even if there's a same username existing.
$conu=mysqli_connect("localhost","db_user","db_pass","db_name");
$result = mysql_query("SELECT 1 FROM member WHERE username = $username");
if ($result && mysql_num_rows($result) > 0) {
$user_err = "<i><span class='error'>Usernme already exists</span></i>";
$errflag = true;
}
elseif(preg_match("/^[0-9a-zA-Z_]{5,}$/", $username) === 0) {
$user_err = "<i><span class='error'>Usernme must be bigger than 5 chararacters and can contain only digits, letters and underscore</span></i>";
$errflag = true;
}
Try
mysql_query("SELECT username FROM member WHERE username = '$username' LIMIT 1;");
SELECT 1 is not actually using the database; it's always returning 1, hence why your result is always the same regardless of the contents of the member table.
Usernames I take it are some sort of varchar? If that is the case, you might want to put its value in quotes:
$result = mysql_query("SELECT `username` FROM `member` WHERE `username` = '".$username."' LIMIT 1;");
your query is subject to sql injections btw.
At first, you are trying to return a column that probably doesn't exist: "1"
Second, I hope that you are cleaning the $username or else you are allowing anyone to inject your database.
The correct query is
mysql_query("SELECT * FROM `member` WHERE `username`='$username'");
You are using mysqli to connect, but mysql to perform your query.
When you SELECT 1 FROM member WHERE username = $username, the result will always be 1.
You need to put $username in the query in quotes. Something like SELECT username FROM member WHERE username = '$username'.
You forgot to include the part of the code for when there is no such username in your posting.
I have the following code in my registration form to prevent against multiple usernames being created:
connect_db();
$check = mysql_query("SELECT username FROM school_users WHERE username = '$username'") or die(mysql_error());
$check2 = mysql_num_rows($check);
if ($check2 != 0) {
respond("error", "Sorry, the username ".$_POST['username']." is already in use. Please choose a different username.");}
However, I also want to check for email, in the same statement:
connect_db();
$check = mysql_query("SELECT username, email FROM school_users WHERE username = '$username' or email = '$email'") or die(mysql_error());
$check2 = mysql_num_rows($check);
if ($check2 != 0) {
if (???username???){
respond("error", "Sorry, the username ".$_POST['username']." is already in use. Please choose a different username.");}}
else if (???email???) {
respond("error", "Sorry, the username ".$_POST['username']." is already in use. Please choose a different username.");}}
You could try doing:
connect_db();
$check = mysql_query("SELECT 'User' validation
FROM school_users
WHERE username = '$username'
UNION ALL
SELECT 'Email'
FROM school_users
WHERE email = '$email'") or die(mysql_error());
$row = mysql_fetch_assoc($check);
if($row)
{
if ($row["validation"] == 'User') {
respond("error", "Sorry, the username ".$_POST['username']." is already in use. Please choose a different username.");}}
else if ($row["validation"] == 'Email') {
respond("error", "Sorry, the email ".$_POST['email']." is already in use. Please choose a different email.");}}
}
OR you could just do it separately...
//Validate UserName
connect_db();
$check = mysql_query("SELECT username FROM school_users WHERE username = '$username'") or die(mysql_error());
$check2 = mysql_num_rows($check);
if ($check2 != 0) {
respond("error", "Sorry, the username ".$_POST['username']." is already in use. Please choose a different username.");}
//Validate Email
connect_db();
$checkEmail = mysql_query("SELECT email FROM school_users WHERE email = '$email'") or die(mysql_error());
$checkEmail2 = mysql_num_rows($check);
if ($checkEmail2 != 0) {
respond("error", "Sorry, the email ".$_POST['email']." is already in use. Please choose a different email.");}
Additionally, your code is vulnerable to SQL Injection attacks and you are using deprecated MySQL php functions. If you do want to make your code better an less vulnerable, take a look at the following links:
Why shouldn't I use mysql_* functions in PHP?
What could i use instead of mysql_ functions?
Prepated Statements
Prepared Statements with MySQLi
The original code isn't that far from the solution as you might think.
$check = mysql_query("SELECT username, email FROM school_users WHERE username = '$username' or email = '$email' LIMIT 1") or die(mysql_error()); //Limit one reduces the time mysql searches the db since it stops on the first occurence
$check2 = mysql_fetch_assoc($check); //we do not only want to know the count of matching rows, but the values return in email and username field
//trimming makes sure we do not have any spaces at the beginning or end
//strtolower makes sure we set UserName == usERnaME == username etc.pp.
if (strtolower(trim($row['username'])) == strtolower(trim($_POST['username']))){ // check the result
respond("error", "Sorry, the username ".$_POST['username']." is already in use. Please choose a different username.");}
}
else if (strtolower(trim($row['email'])) == strtolower(trim($_POST['email']))) { // and again for email adress
respond("error", "Sorry, the email ".$_POST['email']." is already in use. Please choose a different email.");}
}
You can also do this in one statement:
SELECT username
FROM school_users
WHERE username = '$username' or email = '$email'
If you do this, you'll need to change the message to the user . . . "Your user name or email (or both) are already in use".
To customize the message in one statement, you can use aggregation:
select (case when max(username = '$username') = 1 and max(email = '$email' = 1
then 'both'
when max(username = '$username') = 1
then 'username'
when max(email = $email) = 1
then 'email'
end) as WherePresent
from school_users
WHERE username = '$username' or email = '$email'
This returns 0 rows if everything is ok. Otherwise, it returns one row with one of "both", "username", "email", indicating which is duplicated.