重复一个功能

时间:2010-12-26 18:04:02

标签: php mysql function uniqueidentifier

这是问题I posted here的后续问题。

我使用以下代码为用户提供唯一ID:

function NewGuid() { 
    $s = strtoupper(uniqid(rand(),true)); 
    $guidText = substr($s,0,8) . '-' . substr($s,8,4) . '-' . substr($s,12,4). '-' . substr($s,16,4). '-' . substr($s,20); return $guidText; 
} 

$Guid = NewGuid();
echo $Guid;

$alphabet = '123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ';

function base_encode($num, $alphabet) { 
    $base_count = strlen($alphabet); 
    $encoded = '';

    while ($num >= $base_count) {
        $div = $num/$base_count;
        $mod = ($num-($base_count*intval($div)));
        $encoded = $alphabet[$mod] . $encoded;
        $num = intval($div);
    }

    if ($num) $encoded = $alphabet[$num] . $encoded;
    return $encoded;    
}

function base_decode($num, $alphabet) { 
    $decoded = 0;
    $multi = 1;

    while (strlen($num) > 0) {
        $digit = $num[strlen($num)-1];
        $decoded += $multi * strpos($alphabet, $digit);
        $multi = $multi * strlen($alphabet);
        $num = substr($num, 0, -1);
    }

    return $decoded;
}

echo base_encode($Guid, $alphabet);

因此,如果生成的id已经被使用,我希望此代码能够重复,直到生成一个全新的id并输入到数据库中。另外我是编程新手,所以请随意详细说明;)

有什么想法?感谢。

5 个答案:

答案 0 :(得分:2)

非常容易。

你有3个功能。

一个 - 主要生成guid功能。
Two - Sub生成guid函数 三 - 子插入guid功能。

子生成功能:
实际生成是否会返回一个guid。

子插入功能:
尝试将guid插入数据库。失败时返回false / null。真/成功的数据。

主要功能:
循环中:
调用子功能来获取指导 调用子函数以插入guid为唯一键或主键的数据库中 失败时,重新启动循环 成功退出循环并返回guid。

示例:

function GetGuid()
{
    do
    {
        $guid = GenerateGuid();
    } while (!InsertGuid($guid));
    return $guid;
}

function GenerateGuid()
{
    // do your stuff here.
    return $guid;
}

function InsertGuid($guid)
{
    $sql = 'INSERT INTO `guid_table` (`guid`) VALUES ('$guid')';
    $connection = //do sql connect here;
    return // do sql execution here which will return false/null on failure;
}

答案 1 :(得分:1)

function randr($j = 8){
$string = "";
    for($i=0;$i < $j;$i++){
        srand((double)microtime()*1234567);
        $x = mt_rand(0,2);
        switch($x){
            case 0:$string.= chr(mt_rand(97,122));break;
            case 1:$string.= chr(mt_rand(65,90));break;
            case 2:$string.= chr(mt_rand(48,57));break;
        }
    }
return $string; 
}

    do{
    $id = randr();
    $check = mysql_query("SELECT uniq FROM users WHERE uniq = '$id'");
    }while(mysql_num_rows($check) != 0);

想一想。

答案 2 :(得分:1)

我必须升级/修复一个与编码方式类似的系统,我得告诉你,我真的变得讨厌原来的程序员。

考虑一下您正在做什么,如果另一个用户在您询问guid是否有效(并且返回是)之间创建了一个帐户,并且当您实际插入该行时,您仍然可能发生冲突。那太可怕了......

但是那些制作数据库程序的人会想到这一点并为您提供一个无痛的替代方案:标识列。它们提供了三大优势:

  • 保证是唯一的(或插入失败)
  • 它们会自动成为主键
  • 数据库会为您生成

要使用它们,请将您的ID列设置为标识列,并在执行插入时将其写为:

insert into users (name, passwordhash, extrastuff) 
values (@name, @passwordhash, @extrastuff);
select @@identity -- or ident_current() for mysql

然后您返回为您生成的用户ID,以便进一步处理。无论有多少用户同时尝试此操作,这都是同时完成的。

答案 3 :(得分:0)

之前我构建了类似的代码,我通常从一个null变量开始,我一边做($ variable == null){}

在while内部,我创建新代码对数据库进行检查,如果它还不存在,我设置$ variable = $ new_code(这将打破while),然后相应地继续。

此外,我记录可能发生的任何碰撞

希望这会有所帮助

答案 4 :(得分:0)

可能是一种略有不同的方法

我会将我的生成逻辑移到存储过程中,并要求数据库生成一个像oracle中一样的唯一序列。

通过这种方式,我可以避免多次出行以检查号码是否唯一。