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.
Related
I am developing an app using Laravel which will have a functionality to register user.
I want to provide customized unique id to every user (ie: User_id = SM129).
Userid will have following features:
1) User id will be auto-generated while registering.
2) Auto-generated user id should be Check to a database for its uniqueness.
Currently, I am using following code to generated unique user id based on current date. but there is a chance of duplicity on a username with this. Please help
<?php
//creates a unique id for user id
echo "<br>";
$day = date('D');
$month = date('F');
$year = date('Y');
$fmonth = substr($month, 0, 1);
$fyear = substr($year, 2, 2);
$fday = substr($day, 0, 1);
$uniq = rand();
$funiq = substr($uniq, 0, 2);
$funiq1 = substr($uniq, 0, 1);
$joint= 'ST'.$fmonth.$fday.$funiq1.$fyear.$funiq ;
?>
<input type="text" name="username" value = "<?php echo $joint; ?>">
It looks like it's actually better if you were to implement UUID in your Laravel Application:
https://medium.com/#steveazz/setting-up-uuids-in-laravel-5-552412db2088
UUID is short for “universal unique identifier” which is a set of 36 characters, containing letters and numbers. Each set should be unique, with there only being a chance for repetition each 100 years, you can read more about it and check out some cool statistics here and here.
Also don't put a value on your input - generate the unique ID server side (either in your controller/model).
If you leave the unique value in the input, there's nothing stopping users from actually changing that value.
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.
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;
}`
I have an issue in a PHP script which checks if the tax number has right company name on input some other form fields and insert into MySQL. What I want is to put some control code - maybe "select distinct formCompany from company where formCompany = ".$formCompany." " or some code which checks if taxid is given correctly for the name of company from input form. Does someone have idea of how to do that? Any example is welcome.
I have script which simply input data from form fields into MySQL db:
$db=mysql_connect($hostname, $db_user, $db_password);
mysql_select_db($database,$db);
$taxid=mysql_real_escape_string($_POST['taxid']);
$formCompany=mysql_real_escape_string($_POST['formCompany']);
$formOffice=mysql_real_escape_string($_POST['formOffice']);
$formBr=mysql_real_escape_string($_POST['formBr']);
$formContact=mysql_real_escape_string($_POST['formContact']);
//trim
$id=trim($id);
$taxid=trim($taxid);
$formCompany=trim($formCompany);
$formOffice=trim($formOffice);
$formBr=trim($formBr);
$formContact=trim($formContact);
if($_POST['taxid']==''||$_POST['formCompany']=='') {
echo '<p style="color: red">Input relevant data!<p>';
} else {
$sql = "INSERT INTO company (taxid, formCompany,formOffice,formBr,formContact) VALUES ('$taxid','$formCompany','$formOffice','$formBr', '$formContact')";
if(!$result = mysql_query($sql, $db)) {
echo "ERROR: ".mysql_error();
} else {
header("Refresh: 0; url=main.php");
}
}
First, add this code before the if statement
$taxcheck = mysql_query("SELECT * FROM company WHERE taxid = '" . $taxid . "' ");
if (mysql_num_rows($taxcheck)) { $exists = true; }
else { $exists = false; }
Then change this line
if($_POST['taxid']==''||$_POST['formCompany']=='')
to
if($_POST['taxid'] == "" || $_POST['formCompany'] == "" || $exists == true)
This code will prevent you from ending up with more than one company using one tax ID number.
From what I understand, two companies - formCompany - in your app cannot have the same tax-id - taxid, right? If yes, the simplest way is to create a unique index on company.taxid. Any attempt then to insert another company with the same tax-id will thrown a MySQL error.
Here is the query for adding the unique index:
ALTER TABLE `company` ADD UNIQUE INDEX `idx_u_taxid` (`taxid`);
Hope it helps!
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.