PHP random string for every PDO row - php

I would like to create a random string for every row in my row for the field password - basically its a bulk password generator.
Unfortunately, when I hit the bulk reset button the passwords are reset to all the same string. I would like to have a different random string for each row.
Here is my code:
echo '<form method="post" action=""><input type="submit" name="bulk_password_reset" value="Bulk Password Reset" /></form>';
if (isset($_POST['bulk_password_reset'])) {
$password = generateRandomString();
while ($result = $sqlUpdate->fetch()) {
$sqlUpdate = $dbh->prepare("UPDATE $tableName SET password = :password");
$sqlUpdate-> execute(array(':password'=>$password));
$sqlUpdate->execute();
header('Location: su_password_reset.php');
}
}
Here is my random string generator function:
//Generate random password
function generateRandomString($length = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$randomString = '';
for ($i = 0; $i < $length; $i++) {
$randomString .= $characters[rand(0, strlen($characters) - 1)];
}
return $randomString;
}
What am I doing wrong please?

You should place $password = generateRandomString(); inside while loop, and also add WHERE condition (I assume, you have id in your table) to apply each UPDATE to only one row.
$sqlSelect = $dbh->query("SELECT id FROM $tableName"); // select ids where you want to change passwords
while ($result = $sqlSelect->fetch()) {
$password = generateRandomString();
$sqlUpdate = $dbh->prepare("UPDATE $tableName SET password = :password WHERE id = :id");
$sqlUpdate->execute(array(':password'=>$password, ':id'=>$result['id']));
header('Location: su_password_reset.php');
}
UPD I am no pretty sure about syntax, but this gives you an idea, what you need to do (select id for each row, generate password, then update password for this row only).

This seems to be the problem:
UPDATE $tableName SET password = :password
You aren't specifying a WHERE clause in your UPDATE statement, so it is being applied to the entire column rather than a specific row.

Move this inside your while loop:
$password = generateRandomString();
Currently you're calculating the $password just once, then using that value for every row.
Additionally, your UPDATE clause isn't restricted to any matching criteria. Each cycle through the loop, you're updating every row in the table. You need to add a WHERE clause to restrict the update to that particular row.

Try moving your $password = generatRandomString() inside your while loop
while ($result = $sqlUpdate->fetch()) {
$password = generateRandomString();
$sqlUpdate = $dbh->prepare("UPDATE $tableName SET password = :password");
$sqlUpdate-> execute(array(':password'=>$password));
$sqlUpdate->execute();
header('Location: su_password_reset.php');
}

<?php
$password = generateRandomString(); // Move this inside your while loop
while ($result = $sqlUpdate->fetch())
{
$password = generateRandomString(); // Like so...
}
// Change function generateRandomString($length = 10) {...} to...
function generateRandomString()
{
return md5(rand().time());
}
And add a where clause to your update query.

Related

Random UserID in PHP and MySQL

I have a PHP project in which i want to create and assign random User IDs to my customers when they sign-up in to our company's second website. It must be random generated user Ids that must not duplicate in our MySQL Database. User IDs should be like XYZ654986, HPR654986, WRU934765, SYW365824.
How can I create , check and insert user IDs like these ?
First of all, while random IDs for public services (like YouTube Video IDs) in the URL are useful, internally you shouldn't use random IDs. An ID which is used only backend could be made with AutoIncrement.
Nevertheless, you could have specific reasons to use a random ID.
First, you need to create a random code.
This creates a random code with the length 10 (you can change the length by changing $i<10):
$char = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
$chars = explode ( ",", $char );
$code = "";
for ($i=0; $i<10; $i++) {
$random = rand(0, (count($chars)-1));
$code .= $chars[$random];
}
Then, you need to check whether the code is already used or not.
If you have the codes in your MySQL database, you can use this:
$EveryID = array();
$statement = $pdo->prepare("SELECT ID FROM MyDatabase");
$statement->execute();
while($row = $statement->fetch()) {
array_push($EveryID, $row["ID"]);
}
$IDexists = false;
for ($i=0; $iy<count($EveryID), $i++) {
if ($EveryID[$i] == $code) {
$IDexists = true;
break;
}
}
And if $IDexists is true, you need to do the same (generate new code, etc.). I would do this with a while loop.
If $IDexists is false, you have a new unused code in $code. Then, you need to insert this code with other user information (e.g. name).
Here the full code:
$IDexists = true;
while ($IDexists == true) {
$char = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
$chars = explode ( ",", $char );
$code = "";
for ($i=0; $i<10; $i++) {
$random = rand(0, (count($chars)-1));
$code .= $chars[$random];
}
$EveryID = array();
$statement = $pdo->prepare("SELECT ID FROM MyDatabase");
$statement->execute();
while($row = $statement->fetch()) {
array_push($EveryID, $row["ID"]);
}
$IDexists = false;
for ($i=0; $iy<count($EveryID), $i++) {
if ($EveryID[$i] == $code) {
$IDexists = true;
break;
}
}
}
$statement = $pdo->prepare("INSERT INTO MyDatabase (ID, name, something) VALUES (:ID, :name, :sth)");
$statement->execute(array("ID" => $code, "Name" => $name, "sth" => $Something));
Requirements for this method are that you've made a PDO connection with your database at the beginning of your .php file. If you haven't made that, just google "php MySQL PDO" and look at a tutorial.
At last, I just want to say: If you use the IDs internally (that means the IDs aren't in the URL to the user's site), I'd recommend to make an Auto-Increment ID (that means, the first user has the ID 1, the second 2, etc.). You can set the ID in PhpMyAdmin as primary and check auto-Incrediment to do this (there are tutorials for this, too). That's way easier and for most use-cases more practical (but only if the IDs aren't in the URL on any place on your site).
Edit: Instead of
while($row = $statement->fetch()) {
array_push($EveryID, $row["ID"]);
}
you can use
$EveryID = $statement->fetchAll();

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.

PHP: A different random string is generated every time I use the same variable

I'm trying to generate a random string and insert it into a database showing the user that same random string. However, every time I use that variable that contains the random string, its value is changed to a new random string. As a result, the user sees a different random string than the one inserted into the database.
This is at the top of my PHP code:
$token = GenerateRandomString();
This happens when the user submits a form:
$query = "INSERT INTO mytable (token) VALUES ('{$token}')";
$result = mysqli_query($connection, $query);
This is how I show the user the random string generated:
<input type="hidden" name="mytoken" id="mytoken" value="<?php echo $token; ?>" />
This is the function used to generate the random string:
function GenerateRandomString($length = 5){
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$charactersLength = strlen($characters);
$randomString = '';
for ($i = 0; $i < $length; $i++){
$randomString .= $characters[rand(0, $charactersLength - 1)];
}
return $randomString;
}
on the page that the form is submitted to:
$query = "INSERT INTO mytable (token) VALUES ('{$token}')";
that $token should be either $_GET['token'] or $_POST['token'] depending on your form. Don't forget to sanitize it before putting it in the data base
I guess you don't use global variable.
The value of variable will be the same as before if you use global variabel.
$GLOBALS['token'] = $token;
or it depend on how the action you use such as session, but i think it's not good idea using session, except u destroy it after use it.

How to avoid exponential slowdown in PHP/MYSQL?

I'm the owner of an online browser based game that has around 300 players signed up. I've written a script to detect cheaters, but the issue is that the number of queries in said script will grow exponentially.
It works like this:
Send a query that gets player's information.
Inside of the query, run another query that gets the information of every player.
So basically I am running a query that gets every player's name and information, and inside of that query I run another query to get the information from every other player besides themself. I use this to compare and delete cheaters.
The issue is, since I have 300 players, I have to run 300 queries per player. That's 90,000 queries. If I reach 1,000 players, it would be 1,000,000 queries. There has to be a better way to do this.
My code:
<?php
require '../connect.php';
$rulerinfo = $conn->query("SELECT id, rulername, nationname, alliance, email, dateregister, user_agent, lastseen, password FROM players");
while ($rulerinfo2 = $rulerinfo->fetch_assoc()) {
$id = $rulerinfo2['id'];
$rulername = $rulerinfo2['rulername'];
$nationname = $rulerinfo2['nationname'];
$alliance = $rulerinfo2['alliance'];
$email = $rulerinfo2['email'];
$dateregister = $rulerinfo2['dateregister'];
$useragent = $rulerinfo2['user_agent'];
$lastseen = $rulerinfo2['lastseen'];
$password = $rulerinfo2['password'];
$playerinfo = $conn->query("SELECT id, rulername, nationname, alliance, email, dateregister, user_agent, lastseen, password FROM players WHERE id != '$id'");
while ($playerinfo2 = $playerinfo->fetch_assoc()) {
$id2 = $playerinfo2['id'];
$rulername2 = $playerinfo2['rulername'];
$nationname2 = $playerinfo2['nationname'];
$alliance2 = $playerinfo2['alliance'];
$email2 = $playerinfo2['email'];
$dateregister2 = $playerinfo2['dateregister'];
$useragent2 = $playerinfo2['user_agent'];
$lastseen2 = $playerinfo2['lastseen'];
$password2 = $playerinfo2['password'];
$rulerdistance = levenshtein($rulername, $rulername2);
$nationdistance = levenshtein($nationname, $nationname2);
$emaildistance = levenshtein($email, $email2);
$agentdistance = levenshtein($useragent, $useragent2) / 2;
$totaldistance = $rulerdistance + $nationdistance + $emaildistance + $agentdistance;
if ($password == $password2) {
$totaldistance = $totaldistance - 20;
}
if ($totaldistance < 0) {
$totaldistance = 0;
}
}
}
?>
You should only do the query once, put it in an array and work with it from there. I don't see the need to make almost the same query twice. Loop in your array a second time and just check if the id is not the same as the current.
$res = $conn->query("SELECT id, rulername, nationname, alliance, email, dateregister, user_agent, lastseen, password FROM players");
$array=array();
while ($row = $res->fetch_assoc()) {
$array[] = $row;
}
for($i=0; $i<count($array);$i++) {
for($j=0; $j<count($array); $j++) {
if ($i != $j) {
// Call your functions
$rulerdistance = levenshtein($array[$i]['rulername'], $array[$j]['rulername']);
...
}
}
}

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;
}`

Categories