【问题标题】:Generating a truly unique order id in PHP?在 PHP 中生成真正唯一的订单 ID?
【发布时间】:2023-04-03 02:52:01
【问题描述】:

我正在考虑使用这个:http://phpgoogle.blogspot.com/2007/08/four-ways-to-generate-unique-id-by-php.html

我的想法是使用 2 和 3 之间的混合。但我的问题是,虽然机会很小,但如果我将结果子串为只有5个字符长? 3呢? 2? 1?当然如果它是 1,那么 id 有 1/(26 + 10) 的机会是相同的吗?

【问题讨论】:

  • 发布链接的第一个代码示例已经很糟糕了:他忘记了字符串周围的引号(我不认为这是一个常数)

标签: php unique-key


【解决方案1】:

假设您的用户已通过身份验证并具有用户 ID:

$unique_id = time() . mt_rand() . $userid;

如果同一用户在同一秒内第二次请求此页面,mt_getrandmax() 中仍有可能出现 1,在我的机器上返回 2147483647。您可能会接受吗?

如果您的用户未通过身份验证,您可以根据需要使用其 IP 地址的哈希值。

【讨论】:

    【解决方案2】:

    为什么需要唯一 ID?

    如果您想在您的数据库中生成一个唯一的 ID,则使用自动增量将其留给您的数据库。

    无论如何,您可以结合使用 microtime() 和 rand()。你很独特。

    编辑,相对于 OP 的评论:

    你不能有一个“永远独一无二的”如果。或者,如果你找到了方法,你将赢得图灵奖。

    更好的数学方法会让您体验到“是的,但是在 15645736536475 次中,我会被搞砸的”。

    唯一的方法是使用计数器,每次需要新 ID 时都会递增。数据库就是这样做的。为什么插入前需要Id?

    【讨论】:

    • 在提交到数据库之前,我想要一个唯一的 ID。我同意,这将是“非常独特的”。我怎样才能得到一个总是独一无二的,而不将它存储在数据库中。
    • 你认为这怎么可能?要生成一个“始终唯一的 id”,您不仅需要知道之前生成的所有 id,还需要知道任何将要生成的 id……玩得开心,弄清楚如何做到这一点……
    • @x3ro: 有点夸张...如果你假设算法本身不会改变,那么你可以通过知道任何一个来保证唯一的ID过去的 ID 所有未来的 ID。而使用我们目前的技术,前者更容易实施!
    【解决方案3】:

    如果您依赖随机字符串,那么是的,理论上两个 ID 可能相同。这就是使用长随机字符串的原因,以使这种可能性不太可能被接受。可以计算概率:例如,如果一个 ID 由当前时间(精确到秒)和一个随机的 5 个字符的字母数字字符串组成,并且假设在同一秒内生成了 3 个 ID,则两个 (或更多)相同的是:1 - (38^5! / (38^5-3)! / 38^5^3) = 3.79e-8。大多数人都会同意,对于实际应用来说,这种可能性不够,这就是为什么您链接到的页面建议使用 10 个字符。

    如果您有会话 ID、用户名等,那么您可以在订单 ID 中使用它来帮助解决问题。

    【讨论】:

    • 我同意数学方法。 IMO 1E-15 开始是可以接受的。
    【解决方案4】:

    取自 PHP 的 uniqid 的手册页:

    $better_token = md5(uniqid(mt_rand(), true));
    

    虽然最好不要使用md5-part(将令牌数量减少到 2^128)

    如果您使用数据库,那么是的,您应该让您的 DBMS 处理 id 的生成

    【讨论】:

      【解决方案5】:

      您可以使用 microtime 和 sha256 散列,也可以不使用散列。

       $generate_order_id  = hash('sha256', microtime() );
      

      【讨论】:

        【解决方案6】:

        如果您使用数据库,您应该让您的 DBMS 处理 id 的生成。

        如果你想自己做,有办法......不是最好的,但它可以完成工作。

        首先从db中获取所有存在的uid,然后做一个do while循环...

        $uids_in_db = []; //<< get here the uids from id. Use array_flip so the uids to be the keys in the array ( because isset is faster than in_array )
        
        do{
        
            $uid = generate_somehow_a_random_uid();
        
        } while ( isset( $uids_in_db[$uid]) );
        

        你想要的那样不会有重复的 uid,如果是这样,那么 do while 将创建一个新的。

        注意:通过使用此方法,您必须对 db 进行额外查询并使用 循环内的函数,所以它不是最快的方法......

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-04-14
          • 1970-01-01
          • 2014-04-12
          • 2018-09-01
          • 1970-01-01
          相关资源
          最近更新 更多