php check duplicate email string - php

I've got small problem checking the duplicate email, I don't know what I've done wrong.
PHP SIDE:
// convert to lower case
$email = $db->real_escape_string(trim(strtolower($_POST['email'])));
$q = $db->query("SELECT email FROM user WHERE email='$email'");
$r = $q->fetch_assoc();
if($email == $r['email']) {
echo 'yes';
} else {
echo 'no';
}
I've got an old record in the database. Some of the emails come mixed with uppercase and lowercase! And most of them are from hotmail email account! How to check email that even contain lower and uppercase?
ie: Donald1990#hotmail.com // it skips the duplicate error?
Hedmunds#hotmail.co.uk
hedmunds#hotmail.co.uk

Actually I think you want
"SELECT LOWER(email) FROM user WHERE LOWER(email)='$email'"

i am using laravel 5, but the concept is same
//check from 1 to 500 records, some DB will timeout if 1 to 5000 or more depends on amount of Data, you may have to increase the timeout limit
$users = Subscribers::all(); // take all users from DB
for ($x = $check_from; $x <= $check_to; $x++){
$check_user = Subscribers::select('id','email')->where('id',$x)->first();
if (!isset($check_user)){ // check for gaps in betw records
echo $x . "- not set<br>";
}
else{
$check_user_id = strtolower(trim($check_user->id));
$check_user_email = strtolower(trim($check_user->email));
foreach ($users as $user){
$user_id = strtolower(trim($user->id));
$user_email = strtolower(trim($user->email));
if ($check_user_email == $user_email AND $check_user_id !== $user_id ){
echo $check_user_id.' - '.$user_id.' - '. $user_email.' - Duplicated records<br>';
//$user->delete();
// choose to delete duplicate or whatever u wanna do with it
}
}
}
}
// need to check email is equal && user_id is not same, then there will be 2 id with same email
My code works but if someone can improve to make it shorter will be better.

Related

How to generate unique username - PHP

I have strings of usernames in array . I want to generate a unique string of username which do not exits in array.(probably with some numbers following the username)
How do I achieve this?
I have summarize the code:
function generate_unique_username(){
$firstname = "james";//data coming from user
$lastname = "oduro";//data coming from user
$new_username = $firstname.$lastname;
$usersnames = array("james39","oduro32","kwame93","elvisasante","frimpong32","edward32","jamesoduro");
//Loop through ARRAY usernames and check elements against VAR $new_username
if (in_array($new_username, $usersnames)) {
//generate new username which is not inside array
//the new generated string should also be check against array to ensure is doens not exit.
}else{
return $new_username;
}
}
Thank you.
Generating username from the stored array is not a good practice, I would suggest you to use the database.
If you are using the database instead of the array, you can use the best method to generate the unique username as following:
function generate_unique_username(){
$firstname = "james";//data coming from user
$lastname = "oduro";//data coming from user
$new_username = $firstname.$lastname;
/* Note: writing here pseudo sql code, replace with the actual php mysql query syntax */
$query = "SELECT COUNT(id) as user_count FROM user WHERE username like '%".$new_username."%'";
$result = mysql_query($query);
$count = $result['user_count'];
if(!empty($count)) {
$new_username = $new_username . $count;
}
return $new_username;
}
I think in this case you should first off try and assign cooler user names to the users then when that fails you go for a number suffix. This is an approach I may use. You may need to change the code to your more preferred and secured mysqli call like using the PDO or MySQLI prepared statement.
//function that will be used to figure out if the user name is available or not
function isAvailable($userName){
global $mysqli;
$result = $mysqli->query("SELECT id FROM users WHERE user_name='$userName'") or die($mysqli->error());
// We know username exists if the rows returned are more than 0
if ( $result->num_rows > 0 ) {
//echo 'User with this username already exists!';
return false;
}else{
return true;
}
}
function generate_unique_username($firstname, $lastname, $id){
$userNamesList = array();
$firstChar = str_split($firstname, 1)[0];
$firstTwoChar = str_split($firstname, 2)[0];
/**
* an array of numbers that may be used as suffix for the user names index 0 would be the year
* and index 1, 2 and 3 would be month, day and hour respectively.
*/
$numSufix = explode('-', date('Y-m-d-H'));
// create an array of nice possible user names from the first name and last name
array_push($userNamesList,
$firstname, //james
$lastname, // oduro
$firstname.$lastname, //jamesoduro
$firstname.'.'.$lastname, //james.oduro
$firstname.'-'.$lastname, //james-oduro
$firstChar.$lastname, //joduro
$firstTwoChar.$lastname, //jaoduro,
$firstname.$numSufix[0], //james2019
$firstname.$numSufix[1], //james12 i.e the month of reg
$firstname.$numSufix[2], //james28 i.e the day of reg
$firstname.$numSufix[3] //james13 i.e the hour of day of reg
);
$isAvailable = false; //initialize available with false
$index = 0;
$maxIndex = count($userNamesList) - 1;
// loop through all the userNameList and find the one that is available
do {
$availableUserName = $userNamesList[$index];
$isAvailable = isAvailable($availableUserName);
$limit = $index >= $maxIndex;
$index += 1;
if($limit){
break;
}
} while (!$isAvailable );
// if all of them is not available concatenate the first name with the user unique id from the database
// Since no two rows can have the same id. this will sure give a unique username
if(!$isAvailable){
return $firstname.$userId;
}
return $availableUserName;
}
//Get the unique user id from your database, for now let's go with 30
$userId = 30;
echo generate_unique_username('john', 'oduro', $userId);
Also, it would be nice to provide a fallback feature where the user can change their user name to any other unique value, in case they do not like the auto-generated value.

How to get which condition has failed if any in a single sql query

This might be odd or not... but I need to find out which condition out of 3 has failed if any...
I explain...
In my query I have 3 condition if all goes fine then no problem, but if one of those conditions fail I need to know which condition or conditions have fail so that I can build a proper response...
Example:
if(strlen($k) == 16 && filter_var($em, FILTER_VALIDATE_EMAIL)) {
$con = $c->Con();
$q = $con->query("SELECT COUNT(*) FROM table WHERE v = '$k' AND ema = '$em' AND ve = '0'");
$r = $q->fetch_row();
if($r > 0) { $q = $con->query("UPDATE table SET ve = '1' WHERE v = '$key' AND emails = '$em'");
if($q){
$mss = 'Ready'; // MS 1
}
} else {
$mss = 'It was ready'; // MS 2
}
} else {
$mss = 'Something is wrong!'; // MS 3
}
So the first query has 3 conditions if all are ok then go to the next "query", BUT, how do I know is one of the conditions fail?... what if [v] is not a match, or if the email is not a match or if ve is not a match... that way I can show a proper message on the MS 2.... instead of a general message...
if v is not equal to $k then $mss = 'Your key is not a match';
if emails is not equal to $ema then $mss = 'Your email was not fund';
if ve is not equal to 0 then $mss = 'Your key has no value';
the thing is that I would like to keep it as short and clean as possible, I can do a separate query for each one of the conditions which is a lazy way to do it but effective...
I can come up with a clunky solution that mostly shifts the work to PHP.
Change you query to SELECT the rows using ORs. To return the set of possible rows.
SELECT v, ema, ve FROM table WHERE v = '$k' OR ema = '$em' OR ve = '0';
Now go through this result set to check the conditions.
Pseduocode
while( $row = fetch_row($result) ){
if( 1 and 2 and 3 ){
//SUCCESS
}
elseif( NOT 1 ){
//1 is the problem
}
elseif( NOT 2 ){
//2 is the problem
}
elseif( NOT 3 ){
//3 is the problem
}
}
1,2,3 are the condition (e.g. 1 = ($row['v'] == $k))
You'll have to figure out what to do about multiple rows, ideally the schema would prevent that.

Regarding unique username

I am dealing with a student portal in which i have to create a unique login username for students. I have their firstname, lastname and DOB in a csv file. I tried to create a unique username using these three params for uniqueness. But it is possible that DOB will be null so it may conflict.
Also some of students which are user of portal for one session i.e for ex: 2012-13 will have details in csv sheet of 2013-14 and if we use same format with any unique timestamp or unique id, for username generation than there will be two username of same user.
I need a solution from which i generate a unique username with available details also can check that a every student enters in database only one time and have only one username.
I hope i am clear with details if not than please give your comments i will improve it.
below is the code which i used to generate Username from csv data ,
Logic - USERNAME = 'first 3 letter of firstname' + 'DOB' + 'first 3 letter of lastname'
foreach($result as $file_data){
//loop throgh the data and find errors
//check the duplicate entry in the file
if(count($accepted)>0){
foreach($accepted as $accepted_user){
if(($file_data['First name'] == $accepted_user['First name']) && ($file_data['Last name'] == $accepted_user['Last name']) && ($file_data['DOB'] == $accepted_user['DOB'] )){
$rejected[]=array("error"=> $this->lang->line('duplicate_entry_in_file'),"line_number"=>$error_count);
}
}
}
// Generate username from Firstname , Lastname & DOB (if null than we add auto generated DOB)
if($file_data['First name']=='' || $file_data['Last name']==''){ // check if first_name last_name and date-of_birth is empty
$rejected[]=array("error"=> "First Name , Last Name not available","line_number"=>$error_count);
}else{
if($file_data['DOB']==''){
$dob=date('dmy',mktime(0,0,0,date("m"),date("d")+1,date("Y")-10)); //
$date_of_birth= $dob['4'].$dob['5']."-".$dob['2'].$dob['3']."-".$dob['0'].$dob['1'];
$dob_username= $dob['0'].$dob['1']."-".$dob['4'].$dob['3']."-".$dob['4'].$dob['5'];
}else{
$dob = $file_data['DOB'];
if(strlen($dob) == 5 ){
$year_of_birth=$dob['3'].$dob['4'];
if($year_of_birth < date('y')){
$date_of_birth= "20".$dob['3'].$dob['4']."-".$dob['1'].$dob['2']."-0".$dob['0'];
$dob_username= "0-".$dob['0']."-".$dob['1'].$dob['2']."20".$dob['3'].$dob['4'];
}elseif($year_of_birth > date('y')){
$date_of_birth= "19".$dob['3'].$dob['4']."-".$dob['1'].$dob['2']."-0".$dob['0'];
$dob_username= "0-".$dob['0']."-".$dob['2'].$dob['1']."19".$dob['3'].$dob['4'];
}
}elseif(strlen($dob) > 5 ){
$year_of_birth=$dob['4'].$dob['5'];
if($year_of_birth < date('y')){
$date_of_birth= "20".$dob['4'].$dob['5']."-".$dob['2'].$dob['3']."-".$dob['0'].$dob['1'];
$dob_username= $dob['0'].$dob['1']."-".$dob['2'].$dob['3']."-20".$dob['4'].$dob['5'];
}else{
$date_of_birth= "19".$dob['4'].$dob['5']."-".$dob['2'].$dob['3']."-".$dob['0'].$dob['1'];
$dob_username= $dob['0'].$dob['1']."-".$dob['2'].$dob['3']."-19".$dob['4'].$dob['5'];
}
}
}
$first_name=$file_data['First name'];
$last_name=$file_data['Last name'];
$dateOfBirth = str_replace("-", '', $dob_username);
if((strlen($last_name) < 3 ) && (strlen($first_name) < 3 ) ){
$username=$last_name.$dateOfBirth.$first_name;
}elseif(strlen($last_name) < 3 ){
// $username=$last_name.$dateOfBirth.substr($first_name, 0, 3);
$username=$last_name.$dateOfBirth. mb_substr($first_name, 0, 3,'UTF-8');
}elseif(strlen($first_name) < 3){
$username=mb_substr($last_name, 0, 3,'UTF-8').$dateOfBirth.$first_name;
}else{
$username=mb_substr($last_name, 0, 3 ,'UTF-8').$dateOfBirth.mb_substr($first_name, 0, 3,'UTF-8');
}
//echo $username."<br/>";
if($user_datas = $this->user_model->user_exist(array('username'=>$username))){
//if user already exist then take the user_id
foreach($user_datas as $user_data){
$user_id=$user_data['id'];
}
//if the user is already in the project for this season
if($this->user_model->user_exist_in_project(array('project_id'=>$project_name,'student'=>$username,'season'=>$season))){
//check users first name and last name if exist
if($user_datas = $this->user_model->user_exist(array('first_name'=>$first_name,'last_name'=>$last_name))){
//if match found then reject this data
$rejected[]=array("error"=> $this->lang->line('student_already_in_project_in_season'),"line_number"=>$error_count);
}else{
$accepted[]=$file_data;
}
}
}else{
$accepted[]=$file_data;
}
}
$error_count++;
}
My answer is going to address the specific problem you had regarding:
I need a solution from which i generate a unique username with
available details also can check that a every student enters in
database only one time and have only one username.
Because you stated that you have "first name", "last name" and "birthday" (which might be null) for each student, and need to create a unique username, I'm going to suggest using a checksum.
The real problem is that the data you have cannot in itself guarantee uniqueness, so even the solution I will suggest is not going to work 100% without you implementing some sort of random salt in the user data.
Here is a code snippet to help you see what I'm thinking:
$fname = "John";
$lname = "Doe";
$bday = "1980-03-01";
$unique_user_string = strtolower($fname . $lname . $bday); // not actually unique if 2 people have same name and birthday
$username = ucfirst(substr($fname, 0, 1)) . ucfirst($lname) . crc32($unique_user_string);
From the above code, you should have a username like: JDoe4246458655
And the nice part is that you can always confirm an existing user by checking the checksum and creating a new one using the user data from your CSV. To get the checksum from the existing username, just do:
$crc = substr($username, -10, 10);
I hope this makes sense.
You can use this function simplly:
$uniqueid2 = md5(uniqid());
$uniqueid = substr($uniqueid2, 0, 8);
And add this $uniqueid variable at the end of their name, so this could lead you to a very unique login.

php if username exist in database increase username by one

I am a bit stuck with my code.
I am practising and would like to achive the following.
Before an user sign up, i want to check the users username exists, if exists than increase the name by one.
So my logic works like this. User gives his/her first and last name, generates an username based on that.
function
function unique_name($first_name, $last_name) {
$username = strtolower($first_name.'.'.$last_name)
$check = mysqL_query(" SELECT username WHERE username = '".$username."' ");
if(count($check == 1)) {
$i = 2;
foreach($check as $user) {
return $user['username'].$i;
$i++;
}
} else {
return $username;
}
}
$username = unique_name($_POST['first_name'], $_POST['last_name']);
// saveing the increased username
So actually the script should check if the generated unique username exsits if exsits increase, and encrease it even if it exsits with a number
example
Tom Anderson signs up, username will be tom.anderson, saved as tom anderson
Second Tom Anderson signs up, username will be tom.anderson, it already exists, save the new one as tom.anderson2.
The third user signs up he is tom anderson too, username tom.anderson* exsits twice, increase to tom.anderson3.
So i dont have a problem checking if the user exsits and saveing it, my problem is, how to increase every username if exist?
I am not asking anybody to write this for me i am nust looking for a hint
Thank you
EDIT
Thank you for the replies but this does not work
if(count($check) == 1) {
$i = 2;
foreach($check as $user) {
return $user['username'].count($check);
$i++;
}
} else {
return $username;
}
This only check the username with out a number, so if username tom.anderson exists it increases to tom.anderson1 but if tom.anderson1 exists too it wont increase to tom.anderson2
Can you have something that just appends the count of the rows returned, unless it's 0?
if(count($check) > 0) {
return $user['username'].count($check);
} else {
return $username;
}
change the SQL:
" SELECT username WHERE username LIKE '".$username."%' "
Try to give like this
if(count($check) == 1) {
$i = 2;
foreach($check as $user) {
return $user['username'].count($check);
$i++;
}
} else {
return $username;
}
You may add new field into user table, and called it base_username.
Them fetch count rows with given username, and increase every username on count found
Something like this
`function unique_name($first_name, $last_name) {
$unique_name = $username = strtolower($first_name.'.'.$last_name)
$cnt = get_row(" SELECT COUNT(*) from `users` WHERE base_username = '".$username."' LIMIT 1 ");
if($cnt){
$unique_name = $username . $cnt + 1;
}
return $unique_name;
}`

Script to update mysql not working

Okay so I have a PHP script that makes a user an artist if vote is high enough. The first part of the script works (the part that does the voting). However, the second part of the script that makes a user an artist does not. It worked before on localhost but is not working on live server for some reason. Either the script has changed and I didn't notice it or there's something wrong with my server config.
I know I should be using mysqli but please don't mention that I am working on it.
To explain how the system works, a form on the voting page is posted to this script and it all runs from there.
There is no error in the error log. Updating the table for //make an artist if vote high enough just doesn't work.
Here's the script:
<?php
session_start();
include("../database.php");
$username = $_SESSION["username"];
$artistname = htmlspecialchars(mysql_real_escape_string($_POST['artistname']));
$trackname = htmlspecialchars(mysql_real_escape_string($_POST['trackname']));
$trackurl = htmlspecialchars(mysql_real_escape_string($_POST['trackurl']));
$flag = 0; // Safety net, if this gets to 1 at any point in the process, we don't upload.
if(isset($_POST['yes'])){
//code runs if vote is yes
//check if user hasnt already voted on track
$result = mysql_query("SELECT username FROM voted WHERE voted='$artistname' AND trackname='$trackname' AND username='$username'")or die(mysql_error());
$check2 = mysql_num_rows($result);
if ($check2 != 0) {
echo('<t1>Sorry, you have already voted on this track. <b>Click next track.</b> </t1>');
$flag = $flag + 1;
}
//code runs if everything is okay
if($flag == 0){
mysql_query("UPDATE members SET vote = vote+1 WHERE artistname='$artistname'
");
echo '<t1><b>You liked the track "'.$trackname.'" by "'.$artistname.'"</t1></b>';
mysql_query("INSERT INTO voted (username, voted,trackname, yesno)
VALUES ('".$username."','".$artistname."','".$trackname."', 'yes')")
or die(mysql_error());
//make an artist if vote high enough
$vote = mysql_query("SELECT vote FROM members WHERE artistname='$artistname'")or die(mysql_error());
if ($vote > 50) {
$artisturl = htmlspecialchars(mysql_real_escape_string(str_replace(' ', '',$_POST['artistname'])));
mysql_query("UPDATE members SET artist='Y', image1='../files/noprofile.jpg', artisturl='$artisturl' WHERE artistname='$artistname'
")or die(mysql_error());
mysql_query("UPDATE tracks SET artist='Y', artisturl='$artisturl' WHERE artistname='$artistname'
")or die(mysql_error());
//email user that has just been made artist
$result = mysql_query("SELECT * FROM members WHERE artistname= '$artistname'");
while($row = mysql_fetch_array($result)){
function spamcheck($field)
{
//filter_var() sanitizes the e-mail
//address using FILTER_SANITIZE_EMAIL
$field=filter_var($row['email'], FILTER_SANITIZE_EMAIL);
//filter_var() validates the e-mail
//address using FILTER_VALIDATE_EMAIL
if(filter_var($row['email'], FILTER_VALIDATE_EMAIL))
{
return TRUE;
}
else
{
return FALSE;
}
}
{//send email
$to = $row['email'];
$subject = "Congratulations! You're now an NBS artist";
$message = "Hi ".$row['artistname'].",
//message removed for condensed code
$from = "";
$headers = 'From:' . "\r\n" .
'Reply-To: ' . "\r\n";
mail($to,$subject,$message,$headers);
}
}
echo '<br><t1>You just made "'.$artistname.'" an artist! <b>Click here</b> to see their profile.</t1>';
}
}
}
You are missing two lines to convert the resource returned by mysql_query() into an integer for the comparison with 50.
$vote = mysql_query("SELECT vote FROM members WHERE artistname='$artistname'")or die(mysql_error());
// Add these two lines
$vote = mysql_fetch_assoc($vote);
$vote = $vote['vote'];
if ($vote > 50) {
...however, all that section could be re-written to use 2 queries instead of 4:
//make an artist if vote high enough
$artisturl = mysql_real_escape_string(htmlspecialchars(str_replace(' ', '',$_POST['artistname'])));
// This effectively combines the first SELECT and the two UPDATEs into one query
$result = mysql_query("
UPDATE members m
LEFT JOIN tracks t ON m.artistname = t.artistname
SET
m.artist = 'Y',
t.artist = 'Y',
m.image1 = '../files/noprofile.jpg',
m.artisturl = '$artisturl',
t.artisturl = '$artisturl'
WHERE m.artistname = '$artistname' AND m.vote > 50
") or die(mysql_error());
// If this affected more than 0 rows, the user was made an artist
if (mysql_affected_rows($result) > 0) {
//email user that has just been made artist
$result = mysql_query("SELECT * FROM members WHERE artistname= '$artistname'");
// ...and so on
Note also that you should pass data through mysql_real_escape_string() as the last operation. So it should go mysql_real_escape_string(htmlspecialchars($data)) rather than the other way around.
I'll throw a dart at this one.
$vote = mysql_query("SELECT vote FROM members WHERE artistname='$artistname'")or die(mysql_error());
if ($vote > 50) {
I don't believe you are converting your mysql_query result into a useful variable. Maybe you were using mysql_fetch_assoc or mysql_num_rows ? Num rows makes more sense if you have an individual record for each vote. If you are summing them up then you can use something like
$output = mysql_fetch_assoc(mysql_query("SELECT vote FROM members WHERE artistname='$artistname'")or die(mysql_error());
$vote = $output['vote'];
Something else to point out is that you aren't using mysql_real_escape_string on your inputs. This is very dangerous and it is strongly encouraged to use this function if you are facing the public internet.

Categories