Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/270.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 插入8个随机字符的唯一字符串_Php_Mysql - Fatal编程技术网

Php 插入8个随机字符的唯一字符串

Php 插入8个随机字符的唯一字符串,php,mysql,Php,Mysql,我正在使用PHP和MySQL以及 我有一个包含3个字段的表(ID,Username,PID) 我希望PID字段包含8个唯一字符的字符串 我的解决方案是在PHP中生成随机字符串并检查它是否存在。如果它存在,那么它将生成另一个字符串 有没有更好的解决方案可以节省处理时间,比如MySQL触发器之类的?字符需要随机吗?还是仅仅是独一无二的?如果它们只需要是唯一的,那么可以使用时间戳。基于时间的价值将确保唯一性 如果您选择另一条路径,则必须根据数据库检查生成的值,直到得到唯一的值。这将为您提供一个随机的8

我正在使用PHP和MySQL以及 我有一个包含3个字段的表(
ID
Username
PID

我希望
PID
字段包含8个唯一字符的字符串

我的解决方案是在PHP中生成随机字符串并检查它是否存在。如果它存在,那么它将生成另一个字符串


有没有更好的解决方案可以节省处理时间,比如MySQL触发器之类的?

字符需要随机吗?还是仅仅是独一无二的?如果它们只需要是唯一的,那么可以使用时间戳。基于时间的价值将确保唯一性


如果您选择另一条路径,则必须根据数据库检查生成的值,直到得到唯一的值。

这将为您提供一个随机的8字符字符串:

substr(str_pad(dechex(mt_rand()), 8, '0', STR_PAD_LEFT), -8);
可在此处找到:

或者,如果用户名字段是唯一的,您也可以使用:

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...
//处理用户注册或其他事宜。。。
函数generateId($sUsername){
返回子序列(md5($sUsername),0,8);
}
$bUnique=假;
$iattests=0;
而(!$bUnique&$IATTERTS<10){
$aCheck=$oDB->findByPID(generateId(“用户名值”);//查询数据库中与生成内容匹配的PID
如果(!$aCheck){//如果没有找到任何内容,则退出循环
$bUnique=正确;
}否则{
$iattests++;
}
}
//保存PID等。。。

。。。这可能只会产生1个“检查”查询,在唯一的情况下可能会产生2个,并将确保一个唯一的字符串。

为什么不以正确的方式执行此操作并使用UUID(也称为GUID),UUID始终是唯一的,无需检查它们是否是唯一的。它可能是36个字符,但您可以将它们存储为十六进制,这样可以节省磁盘空间并提高标准字符数据的速度


您可以阅读上的注释。

如果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等替换,即可生成字符串

您的里程可能会有所不同


--标记

您可以通过这种方式在Mysql中创建8个字符的唯一字符串

CAST(MD5(RAND()) as CHAR(8))
我的解决方案是在PHP中生成随机字符串并检查它是否存在。如果它存在,那么它将生成另一个字符串

这是错误的做法。web服务器将同时运行代码的多个实例,两个实例迟早会在数据库中存储相同的
PID

解决此问题的正确方法是使
PID
唯一
,而不必进行任何预检查。只需运行
INSERT
查询,并检查结果

如果结果是
1062(ER\u DUP\u条目)
错误,请生成新的
PID
,然后重试

任何其他数据库错误都应该像平常一样处理

可能是这样(未经测试):


小心:使用MySQL的时间戳,如果两条记录在一秒内添加,它们可能具有相同的时间戳。Alex,如果可能的话,以毫秒为基础。因此,最好的方法是在php中生成一条,并在数据库中循环检查它是否存在。我想我可以找到一种方法,在一些magin mysql语句中实现这一点,但我不知道。您的PID字段上还应该有一个唯一的键,该键在尝试插入非唯一值时将失败,这为您提供了另一个选项来运行循环以继续尝试,直到成功插入某个值为止。我看到你在做一个图像库,实际上我们总是存储一个当前时间+文件名的md5,然后将文件扩展名弹出到一个“文件”字段中,这总是给我们一个唯一的字符串——我们大约8年来从未遇到过问题。该字段需要允许32个字符+扩展长度——我们通常只使用50.ya,它需要是随机的。感谢您的解决方案,但它可以在mysql触发器中完成吗?还是那样的?这样可以节省处理时间吗?还是不?好的,上面的代码解决方案给出了您所寻找的随机性。为了避免竞争条件,您可以使用md5(microtime(true).$origfilename)存储文件。然后有一个单独的cron进程,该进程通过新的images目录为它们提供正确的文件名,用PID值更新数据库,并通知用户它们的图像已经处理完毕,可以查看了。只是一个想法。您还应该开发一个PID值中不允许的字符串列表。淫秽等等。然后在插入之前根据该列表过滤$pid_offer值。有很多非常不恰当的单词可以用8个或更少的字符拼写!
<?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 */
}