我正在使用PHP和MySQL
我有一个包含3个字段的表格((ID
,Username
,PID
))。
我希望PID
字段包含8个唯一字符的字符串。
我的解决方案是在PHP中生成随机字符串并检查它是否存在。如果它存在,那么它将生成另一个字符串。
有没有更好的解决方案可以节省处理时间,比如MySQL触发器或类似的东西?
答案 0 :(得分:1)
这将为您提供一个随机的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'检查'查询,在特殊情况下可能只有2,并且会确保一个唯一的字符串。
答案 1 :(得分:0)
角色是否需要随机?或者只是独特的?如果它们只需要是唯一的,您可以使用时间戳。以时间为基础的价值将确保独特性。
如果你走另一条路线,你必须检查你对数据库生成的值,直到你得到一个唯一的值。
答案 2 :(得分:0)
为什么不以正确的方式执行此操作并使用UUID(也称为GUID),它们始终是唯一的,无需检查它们是否存在。它可能是36个字符,但您可以将它们存储为HEX,从而节省磁盘空间并提高标准CHAR数据的速度。
您可以阅读PHP doc for functions that do this上的评论。
答案 3 :(得分:0)
你可以用这种方式在Mysql中创建8个字符唯一字符串
CAST(MD5(RAND()) as CHAR(8))
答案 4 :(得分:0)
我的解决方案是在PHP中生成随机字符串并检查它是否存在。如果它存在,那么它将生成另一个字符串。
这是错误的做法。 Web服务器将同时运行您的代码的多个实例,并且迟早,两个实例将在您的数据库中存储相同的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 */
}
答案 5 :(得分:-1)
如果您为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等替换即可生成字符串。
您的里程可能会有所不同。
- 标记