Вставьте уникальные строки из 8 случайных символов - PullRequest
3 голосов
/ 06 января 2010

Я использую PHP и MySQL и У меня есть таблица с 3 полями ((ID, Username, PID)).

Я хочу, чтобы поле PID содержало строки из 8 уникальных символов.

Мое решение - создать случайную строку в PHP и проверить, существует ли она. Если он существует, он сгенерирует другую строку.

Есть ли лучшее решение, которое сэкономит время на обработку, например, триггер MySQL или что-то подобное?

Ответы [ 6 ]

1 голос
/ 06 января 2010

Это даст вам случайную строку из 8 символов:

substr(str_pad(dechex(mt_rand()), 8, '0', STR_PAD_LEFT), -8);

Найдено здесь: http://www.richardlord.net/blog/php-password-security

Или, если поле имени пользователя уникально, вы также можете использовать:

substr(md5('username value'), 0, 8);

Хотя это крайне маловероятно, особенно для md5, ни один из случаев не гарантирует уникальную строку, поэтому я, вероятно, сделал бы что-то вроде этого:

// Handle user registration or whatever...

function generatePID($sUsername) {
    return substr(md5($sUsername), 0, 8);
}

$bUnique = false;
$iAttempts = 0;

while (!$bUnique && $iAttempts < 10) {
    $aCheck = $oDB->findByPID(generatePID("username value")); // Query the database for a PID matching whats generated
    if (!$aCheck) { // If nothing is found, exit the loop
        $bUnique = true;
    } else {
        $iAttempts++;
    }
}

// Save PID and such...

... который, вероятно, даст только 1 запрос 'check', возможно, 2 в уникальных случаях, и обеспечит уникальную строку.

0 голосов
/ 13 июля 2017

Мое решение - создать случайную строку в PHP и проверить, существует ли она. Если он существует, он сгенерирует еще одну строку.

Это неправильный способ сделать это. Веб-сервер будет запускать несколько экземпляров вашего кода одновременно, и рано или поздно два экземпляра будут сохранять одинаковые PID в вашей базе данных.

Правильный способ решить эту проблему - создать столбец PID UNIQUE и не беспокоиться о каких-либо предварительных проверках. Просто запустите запрос INSERT и проверьте результат.

Если в результате возникает ошибка 1062 (ER_DUP_ENTRY), сгенерируйте новый PID и повторите попытку.

Любая другая ошибка базы данных должна рассматриваться как обычно.

Возможно, что-то вроде этого (не проверено):

<?php

/* $link = MySQLi connection */

if (!($stmt = mysqli_prepare ('INSERT `t` (`ID`, `Username`, `PID`) VALUES (?, ?, ?)'))) {
    /* Prepare error */
}
if (!mysqli_bind_param ('iss', $id, $user, $pid) {
    /* Bind error */
}

$e = 0;

for ($i = 0; $i < 10; $i++) {
    $pid = /* generate random string */;
    if (mysqli_stmt_execute ($stmt)) 
        break;  /* success */
    $e = mysqli_stmt_errno ($stmt);
    if ($e !== 1062)
        break;  /* other error */
}
mysqli_stmt_close ($stmt);

if ($e) {
    if ($e === 1062) {
        /* Failed to generate unique PID */
    } else {
        /* Other database error */
    }
} else {
    /* success */
}
0 голосов
/ 08 мая 2012

Вы можете создать уникальную строку из 8 символов в Mysql таким образом

CAST(MD5(RAND()) as CHAR(8))
0 голосов
/ 06 января 2010

Если для PID установлено 8 символов, вам нужно что-то, чтобы сгенерировать строку и убедиться, что она еще не существует.

$alphabet = range('A','Z');

// get all the PIDs from the database
$sql = "select PID from mytable";

// save those all to an array
$pid_array = results of query saved to array

shuffle($alphabet);
$pid_offer = array_slice($alphabet,0,8);

while(in_array($pid_offer, $pid_array)){
    shuffle($alphabet);
    $pid_offer = array_slice($alphabet,0,8);
}

// found uniuqe $pid_offer...

условия гонки все еще существуют.

Если строка не должна быть случайной, то используйте значение идентификатора, которое, вероятно, является целым числом с автоматическим приращением, и начните счет для этого с 10000000.

Тогда просто сделайте простую замену A = 1, B = 2, C = 3 и т. Д. Для цифр в этом числе, чтобы сгенерировать вашу строку.

Ваш пробег может отличаться.

- Mark

0 голосов
/ 06 января 2010

Почему бы не сделать это правильным образом и не использовать UUID (или GUID), которые всегда уникальны, не нужно проверять, есть они или нет. Это может быть 36 символов, но вы получаете преимущество хранения их как HEX, что экономит дисковое пространство и увеличивает скорость по сравнению со стандартными данными CHAR.

Вы можете прочитать комментарии к PHP-документу для функций, которые делают это .

0 голосов
/ 06 января 2010

Должны ли символы быть случайными? Или просто уникальный? Если они должны быть уникальными, вы можете использовать метку времени. Базирование значения на времени обеспечит уникальность.

Если вы идете другим путем, вам придется проверять сгенерированное значение в базе данных, пока не получите уникальное значение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...