I need to prevent generated code from producing duplicate. Is this correct way to do it or are there much more efficient ways?
function generate_code ()
{
$s = get_random_code();
// check if code is already in db
if (is_in_db($s))
return generate_code();
else
return $s;
}
No need to check database,
<?php
uniqid (rand(), true);
?>
What if after generating a code, another duplicated is generated?
function generate_code ()
{
$s = get_random_code();
// check if code is already in db
while (is_in_db($s)) {
$s = get_random_code();
}
return $s;
}
No need to do recursion.
You could use a while loop, to avoid possible recursion depth limits:
function generate_code ()
{
$s = get_random_code();
// check if code is already in db
while (is_in_db($s))
$s = get_random_code();
return $s;
}
Yeah there are. Concatenate you primarykey, add some unique column, if you want. And hash it. I'm not totally sure, but the risk of getting the same hash from 2 different values is really low. Some says, you are more likely to win the lotto, be destroyed by an asteroid and struck by a lighting at the same time.
Related
I am creating short 5 character hashes to make unique classrooms for my students... a typical hash will look like AJ678.
I am generating the hash like this:
public function generateToken($length = 5)
{
return strtoupper(substr(md5(rand()), 0, $length));
}
I am expecting many thousands of classrooms to be generated over the lifetime of the app... so eventually there will be a clash... I want to know how to make sure that every hash will be unique.
I have make the token field a unique field.
I would think that the best way to do this would be to generate the hash, then check if the hash already exists in my database, if it does then generate a new hash, else use the hash.
Is that the correct way to go about this?
EDIT: I am a bit insecure about implementing a function that calls itself... does this look right?
public function generateToken($length = 5)
{
$token = strtoupper(substr(md5(rand()), 0, $length));
if ($this->tokenExistsAlready($token)) {
$this->generateToken();
} else {
return $token;
}
}
public function tokenExistsAlready()
{
$this->db->where('token', $token);
$query = $this->db->get('classes');
if ($query->num_rows() > 0) {
return true;
} else {
return false;
}
}
First, define "unique". Unique in our terms is a string of any length, that does not yet exist in your database.
This pretty much answers your question. You can never be sure, that your string is unique, unless you check it against your database. The longer the string, the slimmer the chance. So in your case, I would have created a while loop checking the database. Starting with the second string you save in the database, you might (and probably will later down the timeline) hit two randomly generated strings in a row. So checking the uniqueness in a loop until you find the "unique" one is a good idea. Something abstract like this:
$token = generateToken();
while(tokenExists($token))
{
$token = generateToken();
}
Keep in mind, that nothing guarantees true uniqueness of a string. You may use the MySQL UUID() or UUID_SHORT(), PHP uniqid() or anything else, that generates a random string. But it still does not guarantee the said uniqueness unless you check it against the existing database.
use uniqid() function
public function generateToken($length = 5)
{
return strtoupper(substr(uniqid(md5(rand()), 0, $length)));
}
Can the token be simply a unique integer? That would be easy to generate with a table with a single, AUTO_INCREMENT, column.
I have a function, that check user language and write it down in a variable. After a time, i come of idea to merge they, so that i need a call the function anytime before the first use of a variable, so i put a call of function inside of var, with a idea, that i would be replace it self. But it does not working, becouse it trying to give me a "Closure Object" back, i think it is a function in clear and not the result :( Here is the important part of code:
$GLOBALS['user_language'] = function()
{
return get_user_language();
}
function get_user_language()
{
$user_language = 'en';
$GLOBALS['user_language'] = $user_language;
return $user_language;
}
//somewhere in the script
print_r($GLOBALS['user_language']);
I wish to get 'en' out, nothing more.
function get_user_language()
{
$user_language = 'en';
$GLOBALS['user_language'] = $user_language;
return $user_language;
}
$GLOBALS['user_language'] = get_user_language();
//somewhere in the script
print_r($GLOBALS['user_language']);
But this is strange because you set it already in get_user_language() then you pull it again. It would almost create a loop. The proper way would probably be to remove the $GLOBALS['user_language'] = $user_language; from the function.
Hope this answers your question.
Just use print_r(get_user_language()) instead of print_r($GLOBALS['user_language']);.
If getting the user's language multiple times would be particularly slow (e.g. a database query would be executed over and over again), you can do something like this:
function get_user_language()
{
static $user_language = null;
if ($user_language === null) {
$user_language = 'en'; // this would be where you make the DB query
}
return $user_language;
}
In practice, in a large PHP application, this code would generally be located in a class and would store the value as an object property, so that, for example, the application can cache DB query results for multiple users rather than for only the current one.
I am trying to grasp the concept of PHP functions. I know how to create one.
function functionName()
{
//code to be executed;
}
I also know how to call a function. I am just a little confused as to what a parameter is for. I have read the php manual and w3schools.com's tutorial. From my understanding, you need a parameter to pass a value to the function? If that is correct why not just create it within the function? Why use a parameter?
Like this:
<?php
function num()
{
$s=14;
echo $s;
}
num();
?>
I know you can do:
<?php
function num($s=14)
{
echo $s;
}
num();
?>
or:
<?php
function num($s)
{
echo $s;
}
num($s=14);
?>
Could someone give me a real application of using a parameter, for say maybe a user based dynamic content website? I think it would help me understand it better.
Passing a parameter allows you to use one function numerous times. For example:
If you wanted to write ONE function that sent mail - you could pass the following parameters:
$to = $_POST['to'];
$from = $_POST['from'];
$subject = $_POST['subject'];
Then, in your function:
function sendmail($to, $from, $subject){
//code to be executed
}
Now you can reuse your send function at various points in your web app.
Here is an example, say you have numbers representing colors (this is common in storing data in a database) and you want to output what number represent's what color.
Say you had to do this a hundrend times for a hundred numbers.
You'd get pretty tired writing 100 if statments 100 times.
Here is a function example...
function colorType($type) {
if ($type == 1) {
return "Green";
}
elseif ($type == 2) {
return "Blue";
}
elseif ($type == 3) {
return "Red";
}
// etc
}
echo colorType(1) . "<br>"; // Green
echo colorType(2) . "<br>"; // Blue
echo colorType(3) . "<br>"; // Red
A function does something, and gives a result. It may accept parameters to arrive at that result, it may not. The simple calculator, as aforementioned, is a good one.
The easiest way to understand functions and parameters is to just read the PHP manual—most of the functions in the core PHP language take parameters of some sort. These functions are no different to the functions you write.
Let's assume you want to create a function that will allow people to sum numbers, you can't write needed variables in functions because you want others to input it and your function shows output:
function add($num1, $num2){
return $num1 + $num2;
}
Now anyone can call/use your function to sum numbers:
echo add(5,1); // 6
echo add(2,1); // 3
echo add(15,1); // 16
That's the most simplest example one can give to explain why you need parameters :)
When you specify function name($var=VALUE), you are setting a default.
function doit($s=14) {
return $s + 5;
}
doit(); // returns 19
doit(3); // returns 8
it makes your functions flexible to be reused in various situations, otherwise you would have to write many functions, one for each scenario. this is not only tedious, but becomes a nightmare if you have to fix something in those functions. instead of fixing it in one place, you would have to fix it in many places. you basically never want to have to copy paste code you have already written, instead you use arguments to make one set of the code flexible enough to handle each situation.
Paramaters allow your function to see the value of variables that exist outside of itself.
For example:
function F_to_C($temp) {
$temp = ($temp - 32) / 1.8;
return $temp;
}
$temperature = 32;
$new_temperature = F_to_C($temperature); // 0
echo $temperature;
$temperature2 = F_to_C(212); // 100
echo $temperature2;
Here we take $temperature, which we define in the code, but could be user input as from a form, and then send it to the function F_to_C. This allows us to convert it to Celsius, so we can then display it thereafter. In the next section, we then re-use the function to convert the boiling point, which is sent directly this time as the value 212. If we had embedded $temperature = 32 in the function the first time, then we would still get 0 as a result. However since we're using parameters, we instead get 100 back, because it's processing the value we specified when we invoked the function.
say if I wanted to give every user that registered on my site a unique id. It seems to me that if I wanted to do this I would have to: Create a random number for the id, check to see if that id already exists in the database, if it does exist then create another random number and send yet another query to see if that exists, and so on...
This could go on for ages. Apart from having an incrementing id, is there any decent way to do this?
The best way to do this is via the auto increment function, if you really don't want to use a function like so you could use uniqid();
Basically you it generates an unique id based on milliseconds, if you put in a kinda unique prefix in the function it will generate a very unique id.
echo uniqid('prefix');
This way you won't have to check after generating an id, if it already exists or not. You can be sure it is unique.
For more information check this url http://php.net/uniqid!
First of all, I agree with the comments. It's all overhead code, and if you're using it to make it look interesting you should really reconsider your priorities.
But, if you still need it; here's a little something:
function uid() {
mt_srand((double)microtime()*1000000);
$token = mt_rand(1, mt_getrandmax());
$uid = uniqid(md5($token), true);
if($uid != false && $uid != '' && $uid != NULL) {
$out = sha1($uid);
return $out;
} else {
return false;
}
}
Basically, it does a lot of random number generating to create a token for uniqueid, and then is sha's that. Probably overhead, but you can be sure that you never generate a double uid.
Fabian.
You can use the rand() function. It will generate a random number between two.
rand(0000,9999)
It will generate a number between 0 and 9999.
To check if it already exist:
$id = rand(0000,9999);
/* CREATE YOUR MYSQL CONNECTION */
$user_list = mysql_query("SELECT * FROM users");
while ($user = mysql_fetch_array($user_list))
{
if ($id == $user['id'])
{
echo('Already exist.');
}
else
{
/* YOUR CODE */
}
}
It's the way I did it...
If you have a string of 15 numbers you are looking at up to 999 trillion, I doubt it will run for "ages" considering there's almost 7 billion people on the planet.
Does the ID need to be numeric? By switching to alphabetic characters you will get a lot more entropy. A 6 digit number is 1,000,000 posibilities, a 6 character alphanumeric string is 2,176,782,336 possibilities. Make it mixed case alphanumeric and that jumps to 15,625,000,000.
Here's how I usually generate unique strings that are as short as possible:
$chars = 'abcdefghijklmnopqrstuvwrxyzABCDEFGHIJKLMNOPQRSTUVWRXYZ0123456789';
mt_srand((double)microtime()*1000000);
$id = '';
do {
$id .= $chars[mt_rand(0, strlen($chars) - 1)];
} while (isIdTaken($id));
var_dump($id);
You have to create a lot of items with this style of id, before you'll get to more than 3 or 4 characters.
I know it's late for this answer but the easiest solution is to generate random number and sure it will be unique 100% is
$uid = uniqid().date("Ymdhhis");
I use the latest code igniter (2.0.3) and php-active 0.0.1.
All are working fine except save();
Code:
if($_POST)
{
$entry= Customers::find_by_routeid('4');
$entry->routeid=5;
$entry->save();
}
Here's my problem: for some reason that I cannot understand the above code does not work, but if I take the code out of if ($_POST), it works fine.
What I am doing wrong?
EDIT:
Thanks Damien Pirsy $this->input->post() does the trick, but when I uncomment the comments in the code the problems returns.
The code now is:
if($this->input->post())
{
$id = $this->input->post('id');
$oldRoute = $this->input->post('oldRoute');
$newRoute = $this->input->post('newRoute');
$entry= Customers::find_by_routeid($this->input->post('oldRoute'));
$entry->routeid=$this->input->post('newRoute');
$entry->save();
/*
if($oldRoute<$newRoute)
{
for ($i=$newRoute; $i>$oldRoute; $i--)
{
$element = Customers::find_by_routeid($i);
echo $element->routeid -= 1;
$element->save();
}
}
*/
}
The elements new IDs ($element->routeid -= 1;) are echoing right, but I have the same problem as in the beginning and neither of two saves work.
You didn't provide much details or debug info, so I'll just guess: try using the CI's native post handler instead. You should have var_dump()ed the $_POST array, see if isset() or not, also, since you're using it as a condition
if($this->input->post())
{
//...
}
UPDATE:
Since we're talking about Post variables, don't assume they're exactly as you want them. Keep in mind that $this->input->post('field') returns FALSE when the index is not present; that might well brake your if condition.
Assuming you need numbers to do this, you can do a check like
if($this->input->post('newRoute') AND is_numeric($this->input->post('newRoute'))
{
$newRoute = $this->input->post('newRoute');
}
else
{
// give it a default value, or raise an error, for example. If you need this
// variables, and need them to be numbers, you cannot go on in case these
// conditions are not met, right?
}
And the same for $oldRoute.
And yeah, OK, maybe you can write a cleaner code than mine, but you get the picture ;)