473,396 Members | 1,893 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Can I put this in a while loop ?

290 100+
I am wanting to create a unique user id for my
clients, so I am taking the first 3 letters of there
name and adding the 4 digits from the rand() function

If the clients namd is david,
this shoud give me something like:

$Db_user = davi7024

Now I want to check that this IS a unique user id so
I look it up in the database.

Now if the record exists, I want to regenerate the user-id with the rand
again and then re-check. If found, do again and re-check again etc.

Do do the multiple re-checks, I guess that I need to put the
look up in a while loop.

But I am not sure how to use the while loop in this case.

This is what I have so far:

Expand|Select|Wrap|Line Numbers
  1. $rand = rand(124,987);
  2. $Db_user = substr($Db_name,0,4).$rand;
  3.  
  4. // Test for unique new contact name.
  5.    $sql = "SELECT * FROM clients WHERE user_id = '$Db_user'";
  6.  
  7.    $result = mysql_query($sql) or die("could not execute FIND MEMBER query");
  8.  
  9. if(mysql_num_rows($result) > 0){
  10.        $rand = rand(124,987);
  11.        $Db_user = substr($Db_name,0,4).$rand;
  12.            exit();
  13.  }  // endif  
Can someone please help me put this in a while
loop so that I ensure unique user_ids ?

Thanks.
Jul 23 '09 #1
17 2612
code green
1,726 Expert 1GB
I would probably do it by SELECT all the current ids and place them in a 1d array.
Then like you say, create a while loop creating random numbers and testing
Expand|Select|Wrap|Line Numbers
  1. while(in_array($yourandno,$dbrandnos))
Just a tip when testing using while loops. Always have a get out clause to prevent infinite loops.ie
Expand|Select|Wrap|Line Numbers
  1. $c++;
  2. if($c>1000) 
  3. break;
But there may be a more efficient way using purely MySql
Jul 23 '09 #2
Dormilich
8,658 Expert Mod 8TB
if you’re fine with plain numbers as user id you can use the AUTO_INCREMENT option for the db field (no need to pass anything at all for user id).
Jul 23 '09 #3
jeddiki
290 100+
Yes I did consider using the auto increment
but felt that as this is a login id, an incremental number
could be easily guessed.

I mean say my user_id is stev078 and I see someone called
Mike also as a new user, I could guess that his user id
will be mike079 or mike080 etc.

Of course there will be a password as well, but I just thought
both should be a bit secure.
So I went for the random number.

Any idea how I put this particular check into a loop ?
Jul 23 '09 #4
jeddiki
290 100+
Hi Code Green
do you mean something like this:

Expand|Select|Wrap|Line Numbers
  1. // Test for unique new contact name.
  2.    $sql = "SELECT user_id FROM clients";
  3.  
  4.    $result = mysql_query($sql) or die("could not execute query.". mysql_error());  
  5.  
  6.    while($Db_user is in $result){
  7.        $rand = rand(124,987);
  8.        $Db_user = substr($Db_name,0,4).$rand;
  9.     }  // endif
  10.  
It's this bit that I am not sure of:
$Db_user is in $result

Do I need to use a for loop to step through all the
elements of the result array - or can I do it more simpler ?
Jul 23 '09 #5
ziycon
384 256MB
Try something like this:
Expand|Select|Wrap|Line Numbers
  1. $rand = rand(124,987);
  2. $Db_user = substr($Db_name,0,4).$rand;
  3.  
  4. // Test for unique new contact name.
  5. $sql = mysql_query("SELECT * FROM clients WHERE user_id = '$Db_user'") or die(mysql_error());
  6. $result = mysql_fetch_array($sql) or die(mysql_error());
  7. while($result) {
  8.     while($Db_user == $result['user_id']) {
  9.         $rand = rand(124,987);
  10.         $Db_user = substr($Db_name,0,4).$rand;
  11.     }
  12. }
Jul 23 '09 #6
code green
1,726 Expert 1GB
It's this bit that I am not sure of:
$Db_user is in $result
You're right this won't work.
You will have to loop through the entire result set first to get the ids in a 1d array
Expand|Select|Wrap|Line Numbers
  1. // Test for unique new contact name. 
  2.    $sql = "SELECT user_id FROM clients";   
  3.    $result = mysql_query($sql) or die("could not execute query.". mysql_error());   
  4.   while($row = mysql_fetch_assoc($result))}
  5.       $allids[] = $row['user_id'];
  6.    }
  7.    //Initialise while loop
  8.    $rand = rand(124,987); 
  9.    $Db_user = substr($Db_name,0,4).$rand; 
  10.    while(in_array($Db_user,$allids)){ 
  11.        $rand = rand(124,987); 
  12.        $Db_user = substr($Db_name,0,4).$rand; 
  13.     }  // endif 
Actually this should be a Do While Loop but will still work
(Check syntax)
Jul 23 '09 #7
bilibytes
128 100+
I would not bother getting all the userIds from the db i would check if it exists:

Expand|Select|Wrap|Line Numbers
  1. //control
  2. $inserted = false;
  3. while($inserted==false){
  4.    //generate the user id
  5.    $userId = ....;
  6.    $resultset = mysql_query('SELECT * FROM users WHERE user_id = $userId');
  7.    if(mysql_num_rows($resultset) == 0){
  8.       //if there is no resultset then it does not exist so make insertion
  9.       mysql_query('INSERT user_id....');
  10.       $inserted = true;//get out of the loop
  11.    }
  12. }
Jul 23 '09 #8
Dormilich
8,658 Expert Mod 8TB
@jeddiki
sure, use one of the available DB handling classes (PDO, MySQLi, MDB2).
Jul 23 '09 #9
code green
1,726 Expert 1GB
Surely this is inefficient bilibytes.
You are executing a query and two functions, an unknown number of times within a while loop.

That is why I suggested collecting all the data in an array with one query.

It could be modified to
Expand|Select|Wrap|Line Numbers
  1. $sql = "SELECT user_id FROM clients";    
  2.    $result = mysql_query($sql) or die("could not execute query.". mysql_error());    
  3.   $unique = false;
  4. while(!$unique){
  5.     $row = mysql_fetch_assoc($result)
  6.     $Db_user = substr($Db_name,0,4).rand(124,987);  
  7.         if( $Db_user !=  $row['user_id'] 
  8.          $unique = true;
  9.  } // endif
Jul 24 '09 #10
вот дурачьё! =)

Expand|Select|Wrap|Line Numbers
  1. do {
  2.     $rand = rand(124,987);
  3.     $Db_user = substr($Db_name,0,4).$rand;
  4.  
  5.     // Test for unique new contact name.
  6.     $sql = "SELECT * FROM clients WHERE user_id = '$Db_user'";
  7.  
  8.     $result = mysql_query($sql) or die("could not execute FIND MEMBER query");
  9. } while (mysql_num_rows($result) > 0);
не благодари.. ^^,
Jul 24 '09 #11
bilibytes
128 100+
@code green
This is an interesting point.
I don't know what is better. and it's a good opportunity for me to make light on the subject.

(your solution here is, if im not wrong, not going to work. Because you need one additional while loop. What you are doing now is loop through all the records in the db with mysql_fetch_assoc() regardless of the number of rows returned by mysql_query() and it will throw an exception when you run out of rows (as you are not checking if there is any row left form mysql_fetch_assoc to loop through.) this is the first problem i see.

But then you have another problem: each time you check if the new generated $DB_user exists, you only check it against the row currently being treated by mysql_fetch_assoc(), and not the entire resultset. This will make you insert the new DB_user on the first row that is not the same to your DB_user, which can be pretty early. So you don't solve the problem). You probably meant to do it so:

Expand|Select|Wrap|Line Numbers
  1. $sql = "SELECT user_id FROM clients";    
  2.    $result = mysql_query($sql) or die("could not execute query.". mysql_error());    
  3. //create an array with db resultset
  4. while($row = mysql_fetch_assoc($result)){
  5. $resultset[] = $row;
  6. }
  7. //will allow us to use a for loop
  8. $dbNumRows = count($resultset);
  9. $unique = false;
  10. while($notUnique){
  11.     $Db_user = substr($Db_name,0,4).rand(124,987);  
  12.         for($i = 0; $i<$dbNumRows; $i++){
  13.               if( $Db_user ==  $resultset[$i]['user_id']{
  14.                     $notUnique = true;
  15.                      break;
  16.               }//endif
  17.         }//endfor
  18. }// endwhile
[/quote]

Let's break the problem into chunks.
n = the number of times the new DB_user name already exists
m = the number of rows returned by the database

-i call rand() as many times as you do.: so it doesn't count.

-i call mysql_query() n times -1 more than you
-you use a for() loop n times more than i do
-you make a string check n times * m rows
-i call mysql_num_rows() n times more than you

:)) i don't want it to become an 'ego' thing, it really is to understand what is faster. (regardless of the fact that your solution is not possible for a production environement, because the database records may have changed (another user was created) before you finish your array check, resulting in a possibility to have duplicate records)

Please, can any one perform the tests? i dont have a good computer to run the tests on.

Thank you

bilibytes
Jul 24 '09 #12
code green
1,726 Expert 1GB
and it will throw an exception when you run out of rows
Well spotted. I missed that. I am too used to using my own database interface class.
But then you have another problem
Yes I see. Did not carefully check my work properly.
I will go back to my un-modified suggestion using in_array(), but the OP did not like my array creation idea
Expand|Select|Wrap|Line Numbers
  1. // Test for unique new contact name.  
  2.    $sql = "SELECT user_id FROM clients";    
  3.    $result = mysql_query($sql) or die("could not execute query.". mysql_error());    
  4.   while($row = mysql_fetch_assoc($result))} 
  5.       $allids[] = $row['user_id']; 
  6.    } 
  7.    //Initialise while loop 
  8.    $rand = rand(124,987);  
  9.    $Db_user = substr($Db_name,0,4).$rand;  
  10.    while(in_array($Db_user,$allids)){  
  11.        $rand = rand(124,987);  
  12.        $Db_user = substr($Db_name,0,4).$rand;  
  13.     }  // endif 
Pretty sure there is not a lot wrong with that.
But I believe this to be more efficient because there is only ONE database call.
Jul 24 '09 #13
Markus
6,050 Expert 4TB
No.

Use an auto-increment ID in your database table, and then use that number coupled with whatever prefix you want to give it. Simple, huh?
Jul 24 '09 #14
jeddiki
290 100+
Thanks for all your input !

I solved it yesterday
with this:

Expand|Select|Wrap|Line Numbers
  1. $rand = rand(124,987);
  2. $Db_user = substr($Db_name,0,3).$rand;
  3.  
  4. // Test for unique new contact name.
  5. $sql = "SELECT user_id FROM clients WHERE user_id = '$Db_user'";
  6. $result = mysql_query($sql) or die(mysql_error());
  7.  
  8. //If member already exists then we are going to keep creating a testing new usernames
  9. while(mysql_num_rows($result) > 0){
  10.     //Then this member name already exists so try another random number
  11.     $rand = rand(124,987);
  12.     $Db_user = substr($Db_name,0,3).$rand;
  13.     $sql = "SELECT user_id FROM clients WHERE user_id = '$Db_user'";
  14.     $result = mysql_query($sql) or die(mysql_error());
  15. }
  16.  
  17. $Db_user = strtolower($Db_user);
  18.  
It works just great :)

I have my random numeric ( better than a sequential one )
and the first letters of the name - easy to remember.

If you see any problems with it, please let me know, but it seems
to be working ok :)

Thanks again
Jul 25 '09 #15
Markus
6,050 Expert 4TB
What if the query inside the while loop also is a duplicate?

[whisper]auto-increment - that's what it's for[/whisper]
Jul 25 '09 #16
bilibytes
128 100+
"[WHISPER]" :)
-> [CRY] auto increment is the only good/efficient solution!! [/CRY]
maybe you will hear it now Jeddiki ;)

Your solution is not an efficient solution.

if you really love rand() function as i can see, you can pair it with auto_increment.
Your table would have an additional field.
Expand|Select|Wrap|Line Numbers
  1.      id         |        user_id                                                | user_name..
  2. auto_increment  |  substr(user_name, 0, 4) . rand(123,987) . auto_increment    | user name
with this you don't need to check for duplication because autoincrement is unique

but again auto_increment alone is sufficient.

ps: your code can be cut down into this:
Expand|Select|Wrap|Line Numbers
  1. $needToCreateUserName = true;
  2. while ($needToCreateUserName){
  3.     $rand = rand(124,987);
  4.     $Db_user = substr($Db_name,0,3).$rand;
  5.     // Test for unique new contact name.
  6.     $sql = "SELECT user_id FROM clients WHERE user_id = '$Db_user'";
  7.     $result = mysql_query($sql) or die(mysql_error());
  8.     //if there are no rows, mysql_num_rows returns 0 wich is false otherwise any number is true
  9.     $needToCreateUserName = (bool) myqsl_num_rows($result);
  10. }
  11. $Db_user = strtolower($Db_user);
bilibytes
Jul 25 '09 #17
Markus
6,050 Expert 4TB
@bilibytes
I'm sayin'! :D
Jul 25 '09 #18

Sign in to post your reply or Sign up for a free account.

Similar topics

9
by: JS | last post by:
#include <stdio.h> main(){ int c, i, nwhite, nother; int ndigit; nwhite = nother = 0; for (i = 0; i < 10; ++i)
6
by: John Pass | last post by:
What is the difference between a While and Do While/Loop repetition structure. If they is no difference (as it seems) why do both exist?
7
by: DaVinci | last post by:
I am writing a pong game.but met some problem. the ball function to control the scrolling ball, void ball(int starty,int startx) { int di ,i; int dj,j; di = 1; dj = 1; i = starty;
1
by: pauljturner99 | last post by:
Hi, I'm trying to pass a parameter from a for loop to the nested while loop but only the first counter is passed. Here is the code: dim ctr redim ctr(5) ctr(0) = 2 ctr(1) = 4 ctr(2) = 6
3
by: libsfan01 | last post by:
hi all in my js code i have a while loop contained within a while loop executed on the basis of a conditional if statement, what i want to do is end the entire function on the last execution on...
14
by: Jan Schmidt | last post by:
Hi, in a nested do-while-loop structure I would like to "continue" the outer loop. With goto this should be no problem in while-loops. However, for do-while I cannot get it to work (without a...
6
by: mgcclx | last post by:
For loop and while loop. which one is faster? I see many articles fighting over it and different people come up with different results.
1
by: somenath | last post by:
Hi All, I have doubt regarding how compiler understands about while loop. For example the bellow mentioned code produce the output as mentioned bellow. #include<stdio.h> int main(void) {
3
by: bmerlover | last post by:
I believe my problem lies inside the while loop. When I click the play button on the gui app, it goes inside the while loop, reads the file and calls the necessary function to do what it needs to do....
3
by: numlock00 | last post by:
I have a nested 'while' loop that won't repeat, no matter how many times the outer loop repeats. The outer loop reads through an array of elements; the inner loop Ithe 'while' loop) is supposed to...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.