How to generate unique random value for each user in laravel and add it to database
I am developing a event organization website. Here when the user registers for an event he will be given a unique random number(10 digit), which we use to generate a barcode and mail it to him. Now,
- I want to make the number unique for each registered event.
- And also random
One solution is to grab all the random numbers in an array and generate a random number using Php rand(1000000000, 9999999999) and loop through and check all the values. Grab the first value that doesn't equal to any of the values in the array and add it to the database.
But I am thinking that there might be a better solution to this. Any suggestion?
php mysql laravel random eloquent
add a comment |
I am developing a event organization website. Here when the user registers for an event he will be given a unique random number(10 digit), which we use to generate a barcode and mail it to him. Now,
- I want to make the number unique for each registered event.
- And also random
One solution is to grab all the random numbers in an array and generate a random number using Php rand(1000000000, 9999999999) and loop through and check all the values. Grab the first value that doesn't equal to any of the values in the array and add it to the database.
But I am thinking that there might be a better solution to this. Any suggestion?
php mysql laravel random eloquent
By "unique for each registered event" do you mean that a random number for event A needs to be distinguishable from a random number for event B?
– Mark Miller
Feb 15 '15 at 8:49
I didn't think of that interpretation, but it seems logical. If yes, my answer would be easy to modify though.
– Joel Hinz
Feb 15 '15 at 8:55
add a comment |
I am developing a event organization website. Here when the user registers for an event he will be given a unique random number(10 digit), which we use to generate a barcode and mail it to him. Now,
- I want to make the number unique for each registered event.
- And also random
One solution is to grab all the random numbers in an array and generate a random number using Php rand(1000000000, 9999999999) and loop through and check all the values. Grab the first value that doesn't equal to any of the values in the array and add it to the database.
But I am thinking that there might be a better solution to this. Any suggestion?
php mysql laravel random eloquent
I am developing a event organization website. Here when the user registers for an event he will be given a unique random number(10 digit), which we use to generate a barcode and mail it to him. Now,
- I want to make the number unique for each registered event.
- And also random
One solution is to grab all the random numbers in an array and generate a random number using Php rand(1000000000, 9999999999) and loop through and check all the values. Grab the first value that doesn't equal to any of the values in the array and add it to the database.
But I am thinking that there might be a better solution to this. Any suggestion?
php mysql laravel random eloquent
php mysql laravel random eloquent
asked Feb 15 '15 at 8:28
Nasif Md. TanjimNasif Md. Tanjim
1,78131730
1,78131730
By "unique for each registered event" do you mean that a random number for event A needs to be distinguishable from a random number for event B?
– Mark Miller
Feb 15 '15 at 8:49
I didn't think of that interpretation, but it seems logical. If yes, my answer would be easy to modify though.
– Joel Hinz
Feb 15 '15 at 8:55
add a comment |
By "unique for each registered event" do you mean that a random number for event A needs to be distinguishable from a random number for event B?
– Mark Miller
Feb 15 '15 at 8:49
I didn't think of that interpretation, but it seems logical. If yes, my answer would be easy to modify though.
– Joel Hinz
Feb 15 '15 at 8:55
By "unique for each registered event" do you mean that a random number for event A needs to be distinguishable from a random number for event B?
– Mark Miller
Feb 15 '15 at 8:49
By "unique for each registered event" do you mean that a random number for event A needs to be distinguishable from a random number for event B?
– Mark Miller
Feb 15 '15 at 8:49
I didn't think of that interpretation, but it seems logical. If yes, my answer would be easy to modify though.
– Joel Hinz
Feb 15 '15 at 8:55
I didn't think of that interpretation, but it seems logical. If yes, my answer would be easy to modify though.
– Joel Hinz
Feb 15 '15 at 8:55
add a comment |
7 Answers
7
active
oldest
votes
Your logic isn't technically faulty. However, if your application attracts lots of users, fetching all of the random numbers may well become unnecessarily expensive, in terms of resources and computation time.
I would suggest another approach, where you generate a random number and then check it against the database.
function generateBarcodeNumber() {
$number = mt_rand(1000000000, 9999999999); // better than rand()
// call the same function if the barcode exists already
if (barcodeNumberExists($number)) {
return generateBarcodeNumber();
}
// otherwise, it's valid and can be used
return $number;
}
function barcodeNumberExists($number) {
// query the database and return a boolean
// for instance, it might look like this in Laravel
return User::whereBarcodeNumber($number)->exists();
}
with mt_rand(1000000000, 9999999999) I am getting only numbers that starts with 11..., 10... and 12... That is one strange random function
– Mladen Janjetovic
Jul 28 '15 at 7:31
add a comment |
You can use php's uniqid() function to generate a unique ID based on the microtime (current time in microseconds)
Example:
<?php
echo uniqid();
?>
Output:
56c3096338cdb
add a comment |
Looping through the array won't be that efficient. If your database becomes too large then it slow down the entire process and also there might be a rare situation when 2 threads are looping through the array for the same random number and it will be found available and return same number to both the tickets.
So instead of looping through the array you can set the 10 digit registration id as primary key and instead of looping through the array you can insert the registration details along with randomly generated number, if the database insert operation is successful you can return the registration id but if not then regenerate the random number and insert.
Alternate solution which will be more effective
Instead of 10 digit random numbers you can use timestamp to generate a 10 digit unique registration number and to make it random you can randomize the first 2 or 3 digits of the timestamp
It doesn't even have to be the primary key. A UNIQUE index will suffice :)
– lukasgeiter
Feb 15 '15 at 12:14
@OP are you still looking for any alternate solution?
– Pavan Jiwnani
Feb 16 '15 at 8:56
add a comment |
This is good:
do {
$refrence_id = mt_rand( 1000000000, 9999999999 );
} while ( DB::table( 'transations' )->where( 'RefrenceID', $refrence_id )->exists() );
add a comment |
<?php
declare(strict_types=1);
namespace AppHelpers;
use AppExceptionsGeneratorException;
class GeneratorHelper
{
public static $limitIterations = 100000;
/**
* @param string $column
* @param string $modelClass
* @return string
* @throws GeneratorException
*/
public static function generateID(string $modelClass, string $column): string
{
return self::run(
$modelClass,
$column,
self::IDGenerator(),
'Generation id is failed. The loop limit exceeds ' . self::$limitIterations
);
}
/**
* @param string $modelClass
* @param string $column
* @param Generator $generator
* @param string $exceptionMessage
* @param array $whereParams
* @return string
* @throws GeneratorException
*/
protected static function run(string $modelClass, string $column, Generator $generator, string $exceptionMessage, array $whereParams = ): string
{
try {
foreach ($generator as $id) {
$query = $modelClass::where([$column => $id]);
foreach ($whereParams as $param) {
$query->where(...$param);
}
if (!$query->first()) {
return $id;
}
}
} catch (Throwable $e) {
$exceptionMessage = $e->getMessage();
}
throw new GeneratorException($exceptionMessage);
}
protected static function IDGenerator(): ?Generator
{
for ($i = 1; $i <= self::$limitIterations; $i++) {
yield (string)random_int(1000000000, 9999999999);
}
return null;
}
}
sample usage
$card->number = GeneratorHelper::generateID(Card::class, 'number');
This is a really good answer and should be accepted as an answer. However, what does the GeneratorException.php file look like?
– Ronny-André Bendiksen
Mar 18 at 10:29
add a comment |
I made something like this
/**
* Generate unique shipment ID
*
* @param int $length
*
* @return string
*/
function generateShipmentId($length)
{
$number = '';
do {
for ($i=$length; $i--; $i>0) {
$number .= mt_rand(0,9);
}
} while ( !empty(DB::table('shipments')->where('id', $number)->first(['id'])) );
return $number;
}
add a comment |
To avoid the problem of having to check to see if a matching code exists every time a new one is created, I just catch MySQL's duplicate record exception (error code 1062). If that error is caught, I just call the function again until the save is successful. That way, it only has to generate a new code if it collides with an existing one. Runs a lot faster -- but obviously gets a bit slower as your number of users approaches the number of possible barcodes.
function generateBarcode($user_id) {
try {
$user = User::find($user_id);
$user->barcode = mt_rand(1000000000, 9999999999);
$user->save();
} catch (Exception $e) {
$error_info = $e->errorInfo;
if($error_info[1] == 1062) {
generateBarcode($user_id);
} else {
// Only logs when an error other than duplicate happens
Log::error($e);
}
}
}
So just loop through all the users you want to assign a code to:
foreach(User::all() as $user) {
generateBarcode($user->id);
}
You could also add some logic to escape the function loop if a maximum number of attempts are made, but I've never bothered because collisions are unlikely.
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f28524290%2fhow-to-generate-unique-random-value-for-each-user-in-laravel-and-add-it-to-datab%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
7 Answers
7
active
oldest
votes
7 Answers
7
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your logic isn't technically faulty. However, if your application attracts lots of users, fetching all of the random numbers may well become unnecessarily expensive, in terms of resources and computation time.
I would suggest another approach, where you generate a random number and then check it against the database.
function generateBarcodeNumber() {
$number = mt_rand(1000000000, 9999999999); // better than rand()
// call the same function if the barcode exists already
if (barcodeNumberExists($number)) {
return generateBarcodeNumber();
}
// otherwise, it's valid and can be used
return $number;
}
function barcodeNumberExists($number) {
// query the database and return a boolean
// for instance, it might look like this in Laravel
return User::whereBarcodeNumber($number)->exists();
}
with mt_rand(1000000000, 9999999999) I am getting only numbers that starts with 11..., 10... and 12... That is one strange random function
– Mladen Janjetovic
Jul 28 '15 at 7:31
add a comment |
Your logic isn't technically faulty. However, if your application attracts lots of users, fetching all of the random numbers may well become unnecessarily expensive, in terms of resources and computation time.
I would suggest another approach, where you generate a random number and then check it against the database.
function generateBarcodeNumber() {
$number = mt_rand(1000000000, 9999999999); // better than rand()
// call the same function if the barcode exists already
if (barcodeNumberExists($number)) {
return generateBarcodeNumber();
}
// otherwise, it's valid and can be used
return $number;
}
function barcodeNumberExists($number) {
// query the database and return a boolean
// for instance, it might look like this in Laravel
return User::whereBarcodeNumber($number)->exists();
}
with mt_rand(1000000000, 9999999999) I am getting only numbers that starts with 11..., 10... and 12... That is one strange random function
– Mladen Janjetovic
Jul 28 '15 at 7:31
add a comment |
Your logic isn't technically faulty. However, if your application attracts lots of users, fetching all of the random numbers may well become unnecessarily expensive, in terms of resources and computation time.
I would suggest another approach, where you generate a random number and then check it against the database.
function generateBarcodeNumber() {
$number = mt_rand(1000000000, 9999999999); // better than rand()
// call the same function if the barcode exists already
if (barcodeNumberExists($number)) {
return generateBarcodeNumber();
}
// otherwise, it's valid and can be used
return $number;
}
function barcodeNumberExists($number) {
// query the database and return a boolean
// for instance, it might look like this in Laravel
return User::whereBarcodeNumber($number)->exists();
}
Your logic isn't technically faulty. However, if your application attracts lots of users, fetching all of the random numbers may well become unnecessarily expensive, in terms of resources and computation time.
I would suggest another approach, where you generate a random number and then check it against the database.
function generateBarcodeNumber() {
$number = mt_rand(1000000000, 9999999999); // better than rand()
// call the same function if the barcode exists already
if (barcodeNumberExists($number)) {
return generateBarcodeNumber();
}
// otherwise, it's valid and can be used
return $number;
}
function barcodeNumberExists($number) {
// query the database and return a boolean
// for instance, it might look like this in Laravel
return User::whereBarcodeNumber($number)->exists();
}
answered Feb 15 '15 at 8:46
Joel HinzJoel Hinz
17k44157
17k44157
with mt_rand(1000000000, 9999999999) I am getting only numbers that starts with 11..., 10... and 12... That is one strange random function
– Mladen Janjetovic
Jul 28 '15 at 7:31
add a comment |
with mt_rand(1000000000, 9999999999) I am getting only numbers that starts with 11..., 10... and 12... That is one strange random function
– Mladen Janjetovic
Jul 28 '15 at 7:31
with mt_rand(1000000000, 9999999999) I am getting only numbers that starts with 11..., 10... and 12... That is one strange random function
– Mladen Janjetovic
Jul 28 '15 at 7:31
with mt_rand(1000000000, 9999999999) I am getting only numbers that starts with 11..., 10... and 12... That is one strange random function
– Mladen Janjetovic
Jul 28 '15 at 7:31
add a comment |
You can use php's uniqid() function to generate a unique ID based on the microtime (current time in microseconds)
Example:
<?php
echo uniqid();
?>
Output:
56c3096338cdb
add a comment |
You can use php's uniqid() function to generate a unique ID based on the microtime (current time in microseconds)
Example:
<?php
echo uniqid();
?>
Output:
56c3096338cdb
add a comment |
You can use php's uniqid() function to generate a unique ID based on the microtime (current time in microseconds)
Example:
<?php
echo uniqid();
?>
Output:
56c3096338cdb
You can use php's uniqid() function to generate a unique ID based on the microtime (current time in microseconds)
Example:
<?php
echo uniqid();
?>
Output:
56c3096338cdb
edited Dec 11 '18 at 13:14
jezmck
55221331
55221331
answered Dec 26 '15 at 11:12
Abhijeet Ashok MuneshwarAbhijeet Ashok Muneshwar
1,6912229
1,6912229
add a comment |
add a comment |
Looping through the array won't be that efficient. If your database becomes too large then it slow down the entire process and also there might be a rare situation when 2 threads are looping through the array for the same random number and it will be found available and return same number to both the tickets.
So instead of looping through the array you can set the 10 digit registration id as primary key and instead of looping through the array you can insert the registration details along with randomly generated number, if the database insert operation is successful you can return the registration id but if not then regenerate the random number and insert.
Alternate solution which will be more effective
Instead of 10 digit random numbers you can use timestamp to generate a 10 digit unique registration number and to make it random you can randomize the first 2 or 3 digits of the timestamp
It doesn't even have to be the primary key. A UNIQUE index will suffice :)
– lukasgeiter
Feb 15 '15 at 12:14
@OP are you still looking for any alternate solution?
– Pavan Jiwnani
Feb 16 '15 at 8:56
add a comment |
Looping through the array won't be that efficient. If your database becomes too large then it slow down the entire process and also there might be a rare situation when 2 threads are looping through the array for the same random number and it will be found available and return same number to both the tickets.
So instead of looping through the array you can set the 10 digit registration id as primary key and instead of looping through the array you can insert the registration details along with randomly generated number, if the database insert operation is successful you can return the registration id but if not then regenerate the random number and insert.
Alternate solution which will be more effective
Instead of 10 digit random numbers you can use timestamp to generate a 10 digit unique registration number and to make it random you can randomize the first 2 or 3 digits of the timestamp
It doesn't even have to be the primary key. A UNIQUE index will suffice :)
– lukasgeiter
Feb 15 '15 at 12:14
@OP are you still looking for any alternate solution?
– Pavan Jiwnani
Feb 16 '15 at 8:56
add a comment |
Looping through the array won't be that efficient. If your database becomes too large then it slow down the entire process and also there might be a rare situation when 2 threads are looping through the array for the same random number and it will be found available and return same number to both the tickets.
So instead of looping through the array you can set the 10 digit registration id as primary key and instead of looping through the array you can insert the registration details along with randomly generated number, if the database insert operation is successful you can return the registration id but if not then regenerate the random number and insert.
Alternate solution which will be more effective
Instead of 10 digit random numbers you can use timestamp to generate a 10 digit unique registration number and to make it random you can randomize the first 2 or 3 digits of the timestamp
Looping through the array won't be that efficient. If your database becomes too large then it slow down the entire process and also there might be a rare situation when 2 threads are looping through the array for the same random number and it will be found available and return same number to both the tickets.
So instead of looping through the array you can set the 10 digit registration id as primary key and instead of looping through the array you can insert the registration details along with randomly generated number, if the database insert operation is successful you can return the registration id but if not then regenerate the random number and insert.
Alternate solution which will be more effective
Instead of 10 digit random numbers you can use timestamp to generate a 10 digit unique registration number and to make it random you can randomize the first 2 or 3 digits of the timestamp
answered Feb 15 '15 at 9:03
Pavan JiwnaniPavan Jiwnani
23415
23415
It doesn't even have to be the primary key. A UNIQUE index will suffice :)
– lukasgeiter
Feb 15 '15 at 12:14
@OP are you still looking for any alternate solution?
– Pavan Jiwnani
Feb 16 '15 at 8:56
add a comment |
It doesn't even have to be the primary key. A UNIQUE index will suffice :)
– lukasgeiter
Feb 15 '15 at 12:14
@OP are you still looking for any alternate solution?
– Pavan Jiwnani
Feb 16 '15 at 8:56
It doesn't even have to be the primary key. A UNIQUE index will suffice :)
– lukasgeiter
Feb 15 '15 at 12:14
It doesn't even have to be the primary key. A UNIQUE index will suffice :)
– lukasgeiter
Feb 15 '15 at 12:14
@OP are you still looking for any alternate solution?
– Pavan Jiwnani
Feb 16 '15 at 8:56
@OP are you still looking for any alternate solution?
– Pavan Jiwnani
Feb 16 '15 at 8:56
add a comment |
This is good:
do {
$refrence_id = mt_rand( 1000000000, 9999999999 );
} while ( DB::table( 'transations' )->where( 'RefrenceID', $refrence_id )->exists() );
add a comment |
This is good:
do {
$refrence_id = mt_rand( 1000000000, 9999999999 );
} while ( DB::table( 'transations' )->where( 'RefrenceID', $refrence_id )->exists() );
add a comment |
This is good:
do {
$refrence_id = mt_rand( 1000000000, 9999999999 );
} while ( DB::table( 'transations' )->where( 'RefrenceID', $refrence_id )->exists() );
This is good:
do {
$refrence_id = mt_rand( 1000000000, 9999999999 );
} while ( DB::table( 'transations' )->where( 'RefrenceID', $refrence_id )->exists() );
edited Nov 16 '18 at 5:52
answered Nov 15 '18 at 17:13
Hadi NoteHadi Note
55079
55079
add a comment |
add a comment |
<?php
declare(strict_types=1);
namespace AppHelpers;
use AppExceptionsGeneratorException;
class GeneratorHelper
{
public static $limitIterations = 100000;
/**
* @param string $column
* @param string $modelClass
* @return string
* @throws GeneratorException
*/
public static function generateID(string $modelClass, string $column): string
{
return self::run(
$modelClass,
$column,
self::IDGenerator(),
'Generation id is failed. The loop limit exceeds ' . self::$limitIterations
);
}
/**
* @param string $modelClass
* @param string $column
* @param Generator $generator
* @param string $exceptionMessage
* @param array $whereParams
* @return string
* @throws GeneratorException
*/
protected static function run(string $modelClass, string $column, Generator $generator, string $exceptionMessage, array $whereParams = ): string
{
try {
foreach ($generator as $id) {
$query = $modelClass::where([$column => $id]);
foreach ($whereParams as $param) {
$query->where(...$param);
}
if (!$query->first()) {
return $id;
}
}
} catch (Throwable $e) {
$exceptionMessage = $e->getMessage();
}
throw new GeneratorException($exceptionMessage);
}
protected static function IDGenerator(): ?Generator
{
for ($i = 1; $i <= self::$limitIterations; $i++) {
yield (string)random_int(1000000000, 9999999999);
}
return null;
}
}
sample usage
$card->number = GeneratorHelper::generateID(Card::class, 'number');
This is a really good answer and should be accepted as an answer. However, what does the GeneratorException.php file look like?
– Ronny-André Bendiksen
Mar 18 at 10:29
add a comment |
<?php
declare(strict_types=1);
namespace AppHelpers;
use AppExceptionsGeneratorException;
class GeneratorHelper
{
public static $limitIterations = 100000;
/**
* @param string $column
* @param string $modelClass
* @return string
* @throws GeneratorException
*/
public static function generateID(string $modelClass, string $column): string
{
return self::run(
$modelClass,
$column,
self::IDGenerator(),
'Generation id is failed. The loop limit exceeds ' . self::$limitIterations
);
}
/**
* @param string $modelClass
* @param string $column
* @param Generator $generator
* @param string $exceptionMessage
* @param array $whereParams
* @return string
* @throws GeneratorException
*/
protected static function run(string $modelClass, string $column, Generator $generator, string $exceptionMessage, array $whereParams = ): string
{
try {
foreach ($generator as $id) {
$query = $modelClass::where([$column => $id]);
foreach ($whereParams as $param) {
$query->where(...$param);
}
if (!$query->first()) {
return $id;
}
}
} catch (Throwable $e) {
$exceptionMessage = $e->getMessage();
}
throw new GeneratorException($exceptionMessage);
}
protected static function IDGenerator(): ?Generator
{
for ($i = 1; $i <= self::$limitIterations; $i++) {
yield (string)random_int(1000000000, 9999999999);
}
return null;
}
}
sample usage
$card->number = GeneratorHelper::generateID(Card::class, 'number');
This is a really good answer and should be accepted as an answer. However, what does the GeneratorException.php file look like?
– Ronny-André Bendiksen
Mar 18 at 10:29
add a comment |
<?php
declare(strict_types=1);
namespace AppHelpers;
use AppExceptionsGeneratorException;
class GeneratorHelper
{
public static $limitIterations = 100000;
/**
* @param string $column
* @param string $modelClass
* @return string
* @throws GeneratorException
*/
public static function generateID(string $modelClass, string $column): string
{
return self::run(
$modelClass,
$column,
self::IDGenerator(),
'Generation id is failed. The loop limit exceeds ' . self::$limitIterations
);
}
/**
* @param string $modelClass
* @param string $column
* @param Generator $generator
* @param string $exceptionMessage
* @param array $whereParams
* @return string
* @throws GeneratorException
*/
protected static function run(string $modelClass, string $column, Generator $generator, string $exceptionMessage, array $whereParams = ): string
{
try {
foreach ($generator as $id) {
$query = $modelClass::where([$column => $id]);
foreach ($whereParams as $param) {
$query->where(...$param);
}
if (!$query->first()) {
return $id;
}
}
} catch (Throwable $e) {
$exceptionMessage = $e->getMessage();
}
throw new GeneratorException($exceptionMessage);
}
protected static function IDGenerator(): ?Generator
{
for ($i = 1; $i <= self::$limitIterations; $i++) {
yield (string)random_int(1000000000, 9999999999);
}
return null;
}
}
sample usage
$card->number = GeneratorHelper::generateID(Card::class, 'number');
<?php
declare(strict_types=1);
namespace AppHelpers;
use AppExceptionsGeneratorException;
class GeneratorHelper
{
public static $limitIterations = 100000;
/**
* @param string $column
* @param string $modelClass
* @return string
* @throws GeneratorException
*/
public static function generateID(string $modelClass, string $column): string
{
return self::run(
$modelClass,
$column,
self::IDGenerator(),
'Generation id is failed. The loop limit exceeds ' . self::$limitIterations
);
}
/**
* @param string $modelClass
* @param string $column
* @param Generator $generator
* @param string $exceptionMessage
* @param array $whereParams
* @return string
* @throws GeneratorException
*/
protected static function run(string $modelClass, string $column, Generator $generator, string $exceptionMessage, array $whereParams = ): string
{
try {
foreach ($generator as $id) {
$query = $modelClass::where([$column => $id]);
foreach ($whereParams as $param) {
$query->where(...$param);
}
if (!$query->first()) {
return $id;
}
}
} catch (Throwable $e) {
$exceptionMessage = $e->getMessage();
}
throw new GeneratorException($exceptionMessage);
}
protected static function IDGenerator(): ?Generator
{
for ($i = 1; $i <= self::$limitIterations; $i++) {
yield (string)random_int(1000000000, 9999999999);
}
return null;
}
}
sample usage
$card->number = GeneratorHelper::generateID(Card::class, 'number');
answered Nov 16 '18 at 6:08
TakamuraTakamura
1011212
1011212
This is a really good answer and should be accepted as an answer. However, what does the GeneratorException.php file look like?
– Ronny-André Bendiksen
Mar 18 at 10:29
add a comment |
This is a really good answer and should be accepted as an answer. However, what does the GeneratorException.php file look like?
– Ronny-André Bendiksen
Mar 18 at 10:29
This is a really good answer and should be accepted as an answer. However, what does the GeneratorException.php file look like?
– Ronny-André Bendiksen
Mar 18 at 10:29
This is a really good answer and should be accepted as an answer. However, what does the GeneratorException.php file look like?
– Ronny-André Bendiksen
Mar 18 at 10:29
add a comment |
I made something like this
/**
* Generate unique shipment ID
*
* @param int $length
*
* @return string
*/
function generateShipmentId($length)
{
$number = '';
do {
for ($i=$length; $i--; $i>0) {
$number .= mt_rand(0,9);
}
} while ( !empty(DB::table('shipments')->where('id', $number)->first(['id'])) );
return $number;
}
add a comment |
I made something like this
/**
* Generate unique shipment ID
*
* @param int $length
*
* @return string
*/
function generateShipmentId($length)
{
$number = '';
do {
for ($i=$length; $i--; $i>0) {
$number .= mt_rand(0,9);
}
} while ( !empty(DB::table('shipments')->where('id', $number)->first(['id'])) );
return $number;
}
add a comment |
I made something like this
/**
* Generate unique shipment ID
*
* @param int $length
*
* @return string
*/
function generateShipmentId($length)
{
$number = '';
do {
for ($i=$length; $i--; $i>0) {
$number .= mt_rand(0,9);
}
} while ( !empty(DB::table('shipments')->where('id', $number)->first(['id'])) );
return $number;
}
I made something like this
/**
* Generate unique shipment ID
*
* @param int $length
*
* @return string
*/
function generateShipmentId($length)
{
$number = '';
do {
for ($i=$length; $i--; $i>0) {
$number .= mt_rand(0,9);
}
} while ( !empty(DB::table('shipments')->where('id', $number)->first(['id'])) );
return $number;
}
answered Jul 28 '15 at 9:01
Mladen JanjetovicMladen Janjetovic
7,32064961
7,32064961
add a comment |
add a comment |
To avoid the problem of having to check to see if a matching code exists every time a new one is created, I just catch MySQL's duplicate record exception (error code 1062). If that error is caught, I just call the function again until the save is successful. That way, it only has to generate a new code if it collides with an existing one. Runs a lot faster -- but obviously gets a bit slower as your number of users approaches the number of possible barcodes.
function generateBarcode($user_id) {
try {
$user = User::find($user_id);
$user->barcode = mt_rand(1000000000, 9999999999);
$user->save();
} catch (Exception $e) {
$error_info = $e->errorInfo;
if($error_info[1] == 1062) {
generateBarcode($user_id);
} else {
// Only logs when an error other than duplicate happens
Log::error($e);
}
}
}
So just loop through all the users you want to assign a code to:
foreach(User::all() as $user) {
generateBarcode($user->id);
}
You could also add some logic to escape the function loop if a maximum number of attempts are made, but I've never bothered because collisions are unlikely.
add a comment |
To avoid the problem of having to check to see if a matching code exists every time a new one is created, I just catch MySQL's duplicate record exception (error code 1062). If that error is caught, I just call the function again until the save is successful. That way, it only has to generate a new code if it collides with an existing one. Runs a lot faster -- but obviously gets a bit slower as your number of users approaches the number of possible barcodes.
function generateBarcode($user_id) {
try {
$user = User::find($user_id);
$user->barcode = mt_rand(1000000000, 9999999999);
$user->save();
} catch (Exception $e) {
$error_info = $e->errorInfo;
if($error_info[1] == 1062) {
generateBarcode($user_id);
} else {
// Only logs when an error other than duplicate happens
Log::error($e);
}
}
}
So just loop through all the users you want to assign a code to:
foreach(User::all() as $user) {
generateBarcode($user->id);
}
You could also add some logic to escape the function loop if a maximum number of attempts are made, but I've never bothered because collisions are unlikely.
add a comment |
To avoid the problem of having to check to see if a matching code exists every time a new one is created, I just catch MySQL's duplicate record exception (error code 1062). If that error is caught, I just call the function again until the save is successful. That way, it only has to generate a new code if it collides with an existing one. Runs a lot faster -- but obviously gets a bit slower as your number of users approaches the number of possible barcodes.
function generateBarcode($user_id) {
try {
$user = User::find($user_id);
$user->barcode = mt_rand(1000000000, 9999999999);
$user->save();
} catch (Exception $e) {
$error_info = $e->errorInfo;
if($error_info[1] == 1062) {
generateBarcode($user_id);
} else {
// Only logs when an error other than duplicate happens
Log::error($e);
}
}
}
So just loop through all the users you want to assign a code to:
foreach(User::all() as $user) {
generateBarcode($user->id);
}
You could also add some logic to escape the function loop if a maximum number of attempts are made, but I've never bothered because collisions are unlikely.
To avoid the problem of having to check to see if a matching code exists every time a new one is created, I just catch MySQL's duplicate record exception (error code 1062). If that error is caught, I just call the function again until the save is successful. That way, it only has to generate a new code if it collides with an existing one. Runs a lot faster -- but obviously gets a bit slower as your number of users approaches the number of possible barcodes.
function generateBarcode($user_id) {
try {
$user = User::find($user_id);
$user->barcode = mt_rand(1000000000, 9999999999);
$user->save();
} catch (Exception $e) {
$error_info = $e->errorInfo;
if($error_info[1] == 1062) {
generateBarcode($user_id);
} else {
// Only logs when an error other than duplicate happens
Log::error($e);
}
}
}
So just loop through all the users you want to assign a code to:
foreach(User::all() as $user) {
generateBarcode($user->id);
}
You could also add some logic to escape the function loop if a maximum number of attempts are made, but I've never bothered because collisions are unlikely.
answered Sep 7 '16 at 0:13
possemediapossemedia
1
1
add a comment |
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f28524290%2fhow-to-generate-unique-random-value-for-each-user-in-laravel-and-add-it-to-datab%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
By "unique for each registered event" do you mean that a random number for event A needs to be distinguishable from a random number for event B?
– Mark Miller
Feb 15 '15 at 8:49
I didn't think of that interpretation, but it seems logical. If yes, my answer would be easy to modify though.
– Joel Hinz
Feb 15 '15 at 8:55