【问题标题】:Zend Framework generate unique stringZend Framework 生成唯一字符串
【发布时间】:2011-09-17 21:07:04
【问题描述】:

我想生成一个唯一的 4-6 字符长的 AlphaNumeric 字符串,以与每个记录(用户)一起保存在 db 中。 db 字段具有唯一索引,因此尝试保存预先存在的字符串会产生错误。现在我正在生成一个随机字符串并使用try-catch,所以当添加一条新记录时,如果它引发异常,我会生成另一个随机字符串并尝试再次保存,并且代码会继续尝试直到成功添加记录。整个解决方案不仅看起来很重而且很丑,所以我想改变它。我对优雅的解决方案感兴趣,因此欢迎任何帮助/指导。

【问题讨论】:

  • 这可能是相关的:stackoverflow.com/questions/7194506/…
  • @JohnD 我知道如何生成随机字符串,但主要问题是添加优雅的方法 1)在 zend 框架中生成字符串和 2)确保随机字符串在数据库中唯一,如果它已经存在,则生成一个新的,直到找到一个唯一的字符串
  • 由于它已经被索引,您可以(目前)生成 N 个键,然后在插入之前运行选择查询。然后,您可以在一次往返中找出哪些密钥已被使用,然后继续使用未使用的密钥再次尝试错误。不是真正的解决方案,但我没有找到我正在寻找的相关问题。
  • 这个随机字符串是干什么用的?它是一些用户必须手动输入的字符串吗?它必须有4-6个字符吗?如果您用完了位(即,当所有可能的组合都已生成时)会发生什么?

标签: php zend-framework unique zend-db


【解决方案1】:

根据给定的信息:

  • id 必须是唯一的
  • id 不能是数字
  • id 不得代表连续系列
  • 用户不会输入id

PHP 函数uniqid 正是您所需要的。虽然它返回一个 13 个字符长的十六进制值。


** 编辑 **

是的,uniqid 将返回一个连续的数字,但我们可以轻松解决这个问题。考虑这段代码

class IDGenerator {
   //const BIT_MASK = '01110011';

   static public function generate() {

      $id = uniqid();

      $id = base_convert($id, 16, 2);
      $id = str_pad($id, strlen($id) + (8 - (strlen($id) % 8)), '0', STR_PAD_LEFT);

      $chunks = str_split($id, 8);
      //$mask = (int) base_convert(IDGenerator::BIT_MASK, 2, 10);

      $id = array();
      foreach ($chunks as $key => $chunk) {
         //$chunk = str_pad(base_convert(base_convert($chunk, 2, 10) ^ $mask, 10, 2), 8, '0', STR_PAD_LEFT);
         if ($key & 1) {  // odd
            array_unshift($id, $chunk);
         } else {         // even
            array_push($id, $chunk);
         }
      }

      return base_convert(implode($id), 2, 36);
   }
}

echo IDGenerator::generate();

这会给出类似的结果

ivpa493xrx7
d173barerui
evpoiyjdryd
99ej19mnau2

由于没有添加或修改任何内容,除了将位打乱,不应该有任何重复的值,而且一切看起来都是随机的。瞧!

** 更新 (2014-02-24) **

我从最初发布的那一刻起就更新了这段代码。你可能会发现修改后的版本here

【讨论】:

  • 但是uniqid生成的值是有顺序的,虽然获取两个相邻的值很困难,但是值是有顺序的。
猜你喜欢
  • 1970-01-01
  • 2011-09-24
  • 2021-07-08
  • 2012-06-17
  • 2012-11-21
  • 2010-10-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多