Six digit and uniqueness sound out of sorts. Shame you don't want to use MySQL because that would give you a clean form with the random number being created in the query.
Check the online php manual for random number generation.
<input type="hidden" value="<?php echo mt_rand(100000, 999999);?>" id="rand" name="rand" />
How's that?
diafol
Rhod Gilbert Fan (ardav)
7,792 posts since Oct 2006
Reputation Points: 1,170
Solved Threads: 1,080
unique, and random are mutually exclusive
is probably easiest to serialize
create a file, in this case i keep it in cgi-bin, called countforms.bcnt if you change the name change it for all occurrences in the scritp
chmod writeable to the user that php runs under
contents six digits
000000
then
<?php $file = "/cgi-bin/countforms.bcnt";
$form_id = file_get_contents( $file ) + 1;
$fp = fopen($file, "w");
fputs ($fp, "$form_id");
fclose($fp); ?>
<input type='hidden' name='form_id' value='<?php echo $form_id; ?>'>
maybe not the best way, but one way
or you could have the script only write the updated serial number on form submit so that the number does not increase crazily
almostbob
Posting Sensei
3,149 posts since Jan 2009
Reputation Points: 571
Solved Threads: 376
Thank you for the padding code,
I had in mind before posting, messed up on posting.
It is actually possible to generate something that is both random and unique (the latter via a test against a history list). then it is no longer random, could roll a 6 on a die a hundred times consecutively.
almostbob
Posting Sensei
3,149 posts since Jan 2009
Reputation Points: 571
Solved Threads: 376
<?php echo mt_rand(100000, 999999);?>
works fine for me. You must have done something wrong. Has your form page got a .htm or .html extension? If so, this is the root of the problem - it should be .php.
Use:
<p><?php echo mt_rand(100000,999999);?></p>
mt_rand has been supported since PHP4. It's quicker than rand().
Although I've supplied this suggestion, I wouldn't use it myself. It's as AlmostBob says - random CAN mean non-unique. I'm sure that you know that you won't roll 899999 instances before you hit a duplicate number - this COULD happen within the first 1000 instances:
In fact, statistical approximation show a 'match probability' of greater than even at 1118 instances.
diafol
Rhod Gilbert Fan (ardav)
7,792 posts since Oct 2006
Reputation Points: 1,170
Solved Threads: 1,080
given that countforms.bcnt is a file in the cg-bin directory chmod writeable contents
000000
outputforms.csv is a file in the cgi-bin directory chmod writeable contents
ID,First name, Lastname,email,address,telephone
<?php if ($_POST['email']) {
$firstname=$_POST['firstname'];
$lastname=$_POST['lastname'];
$email=$_POST['email'];
$address=$_POST['address'];
$telephone=$_POST['telephone'];
$countfile = "/cgi-bin/countforms.bcnt";
$outfile = "/cgi-bin/outputforms.csv";
$form_id = file_get_contents( $file ) + 1;
$fp = fopen($file, 'w');
fputs ($fp, sprintf('%06d',$form_id));
fclose($fp);
$fo = fopen($outfile,'a+');
fputs ($fo, "$form_id,$firstname,$lastname,$email,$address,$telephone\n");
fclose($fo);
}
else {
$firstname=$lastname=$email=$address=$telephone=" ";
$form_id='id will be generated on submission';
} ?>
<form action='<?php echo $_SERVER['PHP_SELF']; ?>' method='post'>
<div>ID= <?php echo $form_id." Please record this number for your records"; ?></div>
Firstname <input type=text name='firstname' value="$firstname" />
Lastname <input type=text name='lastname' value="$lastname" />
Email <input type=text name='email' value="$email" />
Address <input type=text name='address' value="$address" />
telephone <input type=text name='telephone' value="$telephone" />
<input type='submit' name='submit' value='submit' />
</form>
not fully tested, creates a csv file of the submitted forms to be loaded into excell, there are dozens of mail handlers already
the input validation is USELESS, I didnt take any care of it, this is a proof of concept not a 'good' script,
almostbob
Posting Sensei
3,149 posts since Jan 2009
Reputation Points: 571
Solved Threads: 376
<?php if ($_POST['email']) { /* check whether the file is loading from the post and assign values to the variables */
$firstname=$_POST['firstname'];
$lastname=$_POST['lastname'];
$email=$_POST['email'];
$address=$_POST['address'];
$telephone=$_POST['telephone'];
$countfile = "/cgi-bin/countforms.bcnt"; /* define the file containing the count */
$outfile = "/cgi-bin/outputforms.csv"; /* define the file containing the form data, in this case a .csv text file containing 1 row of each form submitted */
$form_id = file_get_contents( $file ) + 1; /* read the last form number and increment */
$fp = fopen($file, 'w'); /* open the couint file and erase the contents */
fputs ($fp, sprintf('%06d',$form_id)); /* put the new count number to the count file
fclose($fp);
$fo = fopen($outfile,'a+'); /* open the output file to append the new data to the end /*
fputs ($fo, "$form_id,$firstname,$lastname,$email,$address,$telephone\n"); /* write the form to the output file */
fclose($fo);
}
else {
$firstname=$lastname=$email=$address=$telephone=" "; /* blank all data fields */
$form_id='id will be generated on submission'; /* information prompt */
} ?>
<form action='<?php echo $_SERVER['PHP_SELF']; ?>' method='post'>
<div>ID= <?php echo $form_id." Please record this number for your records"; ?></div>
Firstname <input type=text name='firstname' value="$firstname" />
Lastname <input type=text name='lastname' value="$lastname" />
Email <input type=text name='email' value="$email" />
Address <input type=text name='address' value="$address" />
telephone <input type=text name='telephone' value="$telephone" />
<?php if (!S_POST['email']) {echo "<input type='submit' name='submit' value='submit' />" ;} else { echo "thank you"; }
</form> <!-- normal html form -->
the form submits to itself, on submission it writes the id number into the id field and displays the data entered in other fields,
I delete the submit button on the post-submit form on this one so that it is not submitted over n over
the number is consecutive
the serial number is a simple file containing a six digit number,
the number is initially set to 000000 when the script is installed
the number is read, incremented and written back to the erased file after the form is validated
in this concept the validation is lousy(nonexistent), twas just to try it out
thanks edwinhermann for the code correction
the new six digit number and the input data are written to the output file and to the browser for the user to read
the output file is .csv comma separated values, the initial content of the file is a comma separated list of the field names
the data fields are written comma separated
excell reads csv as spreadsheets,
today I am doing accounts so Im excell in my head
the data could be sent to mail(), to the user and the site owner, or all of the above.
almostbob
Posting Sensei
3,149 posts since Jan 2009
Reputation Points: 571
Solved Threads: 376
@ AB:
$countfile = "/cgi-bin/countforms.bcnt"; /* define the file containing the count */
$outfile = "/cgi-bin/outputforms.csv"; /* define the file containing the form data, in this case a .csv text file containing 1 row of each form submitted */
$form_id = file_get_contents( $file ) + 1; /* read the last form number and increment */
Is the $file variable = $countfile? I couldn't see it referenced previously.
diafol
Rhod Gilbert Fan (ardav)
7,792 posts since Oct 2006
Reputation Points: 1,170
Solved Threads: 1,080
I have used this little routine to create a unique (ascending) sequence number for registrations. These aren't random, they are very predictable. If you are using the number as a unique reference number, then this is probably what you want to do. It uses a text file so you don't need a database. It locks the file because you could have multiple users trying to do this at the same time (so it needs to be done in a serial fashion).
$fc =fopen("reg_ctr.txt","a+") or die("Error!");
flock($fc,LOCK_EX); /* lock the file */
$seq_ctr = fread($fc,10);
$seq_ctr_next = $seq_ctr;
@$seq_ctr_next = $seq_ctr_next+1;
ftruncate($fc,0);
$ret=fwrite($fc,$seq_ctr_next);
fflush($fc);
flock($fc,LOCK_UN); /* unlock the file */
$ret=fclose($fc);
In other cases where "semi-unique" is close enough (the number generated is never used on its own to find the associated information), I have used the time stamp as the reference number. If you use the full ten characters, then it is unique unless two threads request a number in the same second. If you limit it to the last six characters, then it is less unique and you will eventually get some duplicates. If you want it more unique, you use microtime and a much longer number. For this type of use, the time-stamp info can also be combined with some other info (e.g. last name or part of the phone number) to make it even more unique.
chrishea
Nearly a Posting Virtuoso
1,428 posts since Sep 2008
Reputation Points: 210
Solved Threads: 230
@ AB:
Is the $file variable = $countfile? I couldn't see it referenced previously.
Thanks, Ardav, the obvious error, wasnt obvious when I looked at it first time, i searched for bugs, and missed it
$form_id = file_get_contents( $countfile ) + 1;
the editor I am trying this time tries to complete the code, great when you can't remember the parameterss, lousy when you walk away to grab a coffee and havent completed the line
almostbob
Posting Sensei
3,149 posts since Jan 2009
Reputation Points: 571
Solved Threads: 376
Hi,
I also faces this same problem then i found solution which i posted here...
$i=0;
$rand_no="";
while($i<6)
{
$rand_no=$rand_no.rand(0,9);
$i++;
}
echo "6 digit random no.".$rand_no;
I hope this code may help you
Thanks
Tulsa
Tulsa
Junior Poster in Training
77 posts since May 2009
Reputation Points: 13
Solved Threads: 15
It's a shame php doesn't have a python-like zfill() function, then you'd just need the one rand() or mt_rand() call, not 6. Perhaps I'm wrong, anyone out there know of a function? You could always write your own function, like this:
function random_zfill() {
$int = mt_rand(0,999999);
for($i=0; $i<(6-strlen($int)); $i++)$zeroes .= '0';
return $zeroes.$int;
}
$my_number = random_zfill();
Anyway, this is all academic since the thread starter will be using a file-based counter (I assume).
Obviously, you could expand the function to have parameters like start, end etc.
diafol
Rhod Gilbert Fan (ardav)
7,792 posts since Oct 2006
Reputation Points: 1,170
Solved Threads: 1,080