Я использую PHP и MySQL, и у меня есть таблица с тремя полями (( ID
, Username
, PID
)).
Я хочу, чтобы поле PID
содержало строки из 8 уникальных символов.
Мое решение состоит в том, чтобы сгенерировать случайную строку в PHP и проверить, существует ли она. Если он существует, он будет генерировать другую строку.
Есть ли лучшее решение, которое будет экономить время обработки, например, триггер MySQL или что-то в этом роде?
Это даст вам случайную 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 в уникальных случаях и обеспечит уникальную строку.
Должны ли персонажи быть случайными? Или просто уникально? Если они должны быть уникальными, вы можете использовать временную метку. Исходное значение во времени обеспечит уникальность.
Если вы пройдете другой маршрут, вам нужно будет проверить генерируемое значение по отношению к базе данных, пока не получите уникальное значение.
Почему бы вам не сделать это правильно и использовать UUID (так называемые GUID), которые всегда уникальны, не нужно проверять, есть они или нет. Это может быть 36 символов, но вы получаете возможность хранить их как HEX, что экономит дисковое пространство и увеличивает скорость по сравнению с стандартными данными CHAR.
Вы можете прочитать комментарии к PHP-документу для функций, которые это делают .
Вы можете создать уникальную строку 8 символов в Mysql таким образом
CAST(MD5(RAND()) as CHAR(8))
Мое решение состоит в том, чтобы сгенерировать случайную строку в 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 */ }
Если для значения 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...
условия гонки все еще существуют.
Если строка не должна быть случайной, используйте значение ID, которое, вероятно, является целым числом с автоматическим приращением и начнет подсчет для этого значения на уровне 10000000.
Затем просто выполните простую замену A = 1, B = 2, C = 3 и т. Д. На цифры этого числа, чтобы сгенерировать вашу строку.
Ваш пробег может отличаться.
–Отметка