Нужна помощь в создании уникального идентификатора и проверке его отсутствия в БД - PullRequest
0 голосов
/ 08 января 2012

Я пытаюсь создать функцию, которая при запуске создает числовой идентификатор, проверяет, существует ли этот идентификатор в БД и существует ли он, затем создайте другой идентификатор и проверяйте снова, пока он не получит уникальный идентификатор. Я застрял на том, как зациклить функции с функцией

function createUniqueID() {

function buildUnique() {
    $uniqueID = rand(100000000000,999999999999);
    return $uniqueID;
}

function compareWithDB($uniqueID) {
    $s = "SELECT id FROM table WHERE id='{$uniqueID}'";
    $r = mysql_query($s);
    return $r;
}

function countDBRows($r) {
    if(mysql_num_rows($r) >0){
        $f = false; // found   
    } else{
        $f = true;
    }
}

$uniqueID = buildUnique();
$r = compareWithDB($uniqueID);
$f = countDBRows($r);

if (!$f) {
    $uniqueID = 'nope';
}

return $uniqueID;

}

Ответы [ 5 ]

4 голосов
/ 08 января 2012

Вам гораздо лучше вызвать функцию MySQL UUID() и сохранить и вернуть ее значение, если только это значение не должно быть числовым.

SELECT UUID();
2 голосов
/ 08 января 2012

Если вам нужен уникальный номер, просто используйте AUTO_INCREMENT

Если вам нужно уникальное случайное число (почему?), Создайте уникальный индекс в столбце идентификатора и продолжайте попытки, пока не получите нет ошибок. Это лучше для параллелизма: несколько одновременных вызовов могут иметь один и тот же номер и пройти тест. А еще лучше, пусть движок БД делает это с RAND ...

1 голос
/ 09 января 2012

Я отвечаю на свой вопрос, потому что нашел решение создать большое число, которое (вероятно) никогда не будет дублироваться. Я использую три случайные двузначные переменные и три разных синтаксиса даты.

Объединение их дает понять, что они никогда не будут дублироваться, если кто-то не отправит сообщение в течение того же года, недели и с одинаковым количеством секунд в минуте, а также 3 разных случайных числа будут одинаковыми.

Я думаю, что вероятность этого будет исчисляться миллионами, и если будут миллионы сообщений, то я уверен, что у меня будет больше ресурсов для решения этой проблемы.

$rand1 = rand(10,99);
$rand2 = rand(10,99);
$rand3 = rand(10,99);
$date1 = date("s"); // seconds
$date2 = date("y"); // 2 digit year
$date3 = date("W"); // week number (out of 52)
$uniqueID = $date1.$rand1.$date2.$rand2.$date3.$rand3;
return $uniqueID;
1 голос
/ 08 января 2012

Есть и другой способ. Вы можете использовать функцию sha1 () в сочетании со статической переменной, как показано:

function GetUniqueID() {
    static $salt=1;
    $id = sha1("somestring".(string)$salt);
    $salt++;
    return $id;
}

Здесь статическая переменная $ salt сохраняет свое значение между всеми приращениями вызовов, обеспечивая уникальностьИдентификаторы (хэш SHA1). Для большей безопасности можно также произвольно сделать «некоторую строку».

1 голос
/ 08 января 2012

Могу я предложить гораздо более простую и эффективную функцию uniqid, которая сделает это за вас. Он генерирует гарантированные уникальные идентификаторы на основе метки времени в миллисекундах. Сгенерированный идентификатор имеет длину 13 цифр, если вы не решите добавить префикс или использовать дополнительную «энтропию» (больше уникальности).

Редактировать: обратите внимание, что это и цифры, и буквы, возвращаемые функцией.

http://php.net/manual/en/function.uniqid.php

Редактировать 2 : Используя ваш метод здесь, как вкладывать циклы ...

while (true) {
    $uniqueID = buildUnique();
    $r = compareWithDB($uniqueID)
    if (countDBRows($r)) { break; }
}

Ваш уникальный идентификатор затем сохраняется в $ uniqueID. Однако я не одобряю это, потому что это громоздко и неэффективно ... но вы идете! :)

...