CAKEPHP在数据库中的条目上创建唯一代码

时间:2010-11-01 17:37:55

标签: cakephp model

好的抱歉,这里写的信息太少,我做了一些研究:

问题:编写一个模型函数最简单的方法是为蛋糕模型/表格中的每一行创建一个唯一的代码(5个字符),而这些代码还没有代码?

    //create a unique code

    //set the random id length 
    function generateCode()
    {


    while($i > 0)
    {
    $random_id_length = 7; 
    //generate a random id encrypt it and store it in $rnd_id 
    $rnd_id = crypt(uniqid(rand(),1)); 
    //to remove any slashes that might have come 
    $rnd_id = strip_tags(stripslashes($rnd_id)); 
    //Removing any . or / and reversing the string 
    $rnd_id = str_replace(".","",$rnd_id); 
    $rnd_id = strrev(str_replace("/","",$rnd_id)); 
    //finally I take the first 7 characters from the $rnd_id 
    $rnd_id = substr($rnd_id,0,$random_id_length); 

//check if the code is unique
    $i = $this->checkCode($rnd_id);
    }


    return $rnd_id;

    }

    //check to see if the code isnt already in the database
    function checkCode($code)
    {
     $conditions = array("uniqueCode" => $code));
     $result = $this->Visitors->count('all', array('conditions' => $conditions)); 

     return $result;
    }

//check how many has a code
function check()
{
  $conditions = array("NOT" => array ("uniqueCode" => null));
     $result = $this->Visitors->count('all', array('conditions' => $conditions)); 

     return $result;
}

function update()
{

//update until everyone has a code
  while( $i > 0)
{

   $this->generateCode()
    // get next visitors that DONT have a code.
    $conditions = array ("uniqueCode" => null));
    $visitor = $this->Visitors->find('first', array('conditions' => $conditions)); 
    $i = $this->check();

}

echo 'Done';


}

不能让它正常工作,它必须是一种更简单的方法吗?

4 个答案:

答案 0 :(得分:2)

id列怎么样? :

如果你想让它像哈希一样,我想用这个:

substr(str_shuffle("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789,;:!?.$/*-+&@_+;./*&?$-!,"), 0, 5);

你不应该担心检查它是否是唯一的。或者这样做,所以创建一个这样的哈希并尝试在表中找到它,如果它不在那里 - 你的好处。

答案 1 :(得分:2)

在你的模型中,你可以做这样的事情

<?php

function beforeSave() {
    if (empty($this->data[$this->alias]['id'])) {
        $this->data[$this->alias]['id'] = base_convert(uniqid(), 16, 36);
    }
    return $this->data;
}
?>

这将生成10个字符的唯一ID。你可以弄清楚如何创建5个字符的唯一id,也许可以将字符串转换为更高的字符串,但我觉得很难,因为你必须自己创建函数,base_convert的限制为36

答案 2 :(得分:2)

要考虑的一件事是代码的长度。假设您在其中使用大写和小写字符,五个字符的代码具有380,204,032个可能的唯一代码。如果您真正随机创建这些代码,则会rather soon点击您创建重复项的位置。生成22,959 codes后,有50%的碰撞几率。

所以,因为对于每个新代码,你需要检查它是否已经存在,
(顺便说一句,这是一个更优雅的检查):

do {
    $code = /* create code */;
} while (!$this->isUnique(array('code' => $code)));

随着时间的推移,你会越来越多地使用现有的代码,减慢每个代码的生成速度,以至于你可能需要循环100次或更多次才能找到一个独特的代码(只有99%的碰撞几率) 59,177代码)。

如果您只是谈论几千条记录,我不会担心。如果您的数据集可能/应该超出该数据集,您应该考虑代码的不同方案(UUIDs会想到),按顺序生成代码或预先生成所有可能代码的列表,随机播放它并逐个使用代码。

答案 3 :(得分:0)

有很多方法可以做到这一点,你所要做的就是谷歌适当的话。我在PHP手册中找到了它,所以这将是一个很好的起点。

为了使其独一无二,它将基于日期并且将包含某种散列。

进行一些搜索,阅读和学习