如何在PHP中生成唯一的推荐代码

4
我创建了一个电子商务网站,在用户系统中,我创建了一个推荐系统,它的工作原理如下 -> 当访问者创建帐户时,将生成该客户的唯一推荐代码。 我担心当我有很多用户时,推荐代码会匹配到。因此,我想创建唯一的推荐代码。 我的创建方法如下:
$referral_code = strtolower(substr($first_name,0,3)).$this->refer_code(3);

public function refer_code($limit){
    return substr(base_convert(sha1(uniqid(mt_rand())), 16, 36), 0, $limit);
}

在这里,我从用户名中选取前3个字母和3个随机字母,生成的推荐码如下:

illqhx

但是我的老板说这个很难读懂并且向其他人解释。因此,他希望推荐码只包含数字或者从名字中选取3个字母和3个数字自动生成,保证独一无二,并且限制长度为5或6。
请帮我实现。


2
最好在数据库中检查生成的代码是否存在。 - Aakash Tushar
你对这段代码进行过任何碰撞分析吗?两个人拥有相似的姓名并生成相同的代码的统计概率是多少?正如@AakashTushar所提到的,您可以仅在已存在时再次检查并重新生成。 - Thomas Timbul
@ZainShabir 为了编码的简单性和结果的可读性,为什么不采用顺序方式呢?使用名称中的3个字母+4个连续数字,可以让您在发生冲突之前拥有相同名字的10000个客户。但是,如果不使用数字,而使用字母数字组合,则可以获得额外的26种可能性->在发生相同名字冲突之前有36^4种可能性。顺序或随机并不重要。 - Thomas Timbul
我该如何检查呢? - Zain Shabir
我假设你已经设置了一个检查,用于检查用户名/电子邮件是否被占用,账户是否已存在?同样的方式,但是针对推荐码。 - Thomas Timbul
显示剩余6条评论
4个回答

2
尝试这个。
function random_strings($length_of_string) 
{ 
    $str_result = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890abcdefghijklmnopqrstuvwxyz'; 
    return substr(str_shuffle($str_result), 0, $length_of_string); 
} 

// This function will generate 
// Random string of length 10 
echo random_strings(10); 

?> 

用户很难记住这么多内容。 - Zain Shabir
请查看更新的代码,您可以更改所需生成字符串的长度。 - user11988937
您可以使用任何字符串,例如大写的 ABC、小写的 abc123 - user11988937
我没有得到那个变量$referral_code,不是那样的。那个$referral_code变量和那行代码在我的另一个createAccount()函数中。 - Zain Shabir

1
我建议在您的用户类中添加以下内容。您可以从外部使用createReferralCode来检索代码。它将始终返回相同的值。您也可以仅返回$this并使用访问器方法来检索该值。
关于如何保存或验证您的新密钥,我将留给您自己决定。
/**
 * Referral Code
 *
 * @var string
 */
protected $referralCode;

/**
 * Create a referral code and store it on the User.
 *
 * @return string
 */
public function createReferralCode() : string
{
    if (empty($this->referralCode)) {
        // attempt to create a referral code until the one you have is unique
        do {
            $referralCode = $this->generateReferralCode();
        } while (!$this->hasUniqueReferralCode($referralCode));

        $this->referralCode = $referralCode;
    }

    return $this->referralCode;
}

/**
 * Generate a referral code.
 *
 * @return string
 */
protected function generateReferralCode() : string
{
    // generate crypto secure byte string
    $bytes = random_bytes(8);

    // convert to alphanumeric (also with =, + and /) string
    $encoded = base64_encode($bytes);

    // remove the chars we don't want
    $stripped = str_replace(['=', '+', '/'], '', $encoded);

    // get the prefix from the user name
    $prefix = strtolower(substr($this->firstName, 0, 3));

    // format the final referral code
    return ($prefix . $stripped);
}

/**
 * Check if the referral code is unique.
 *
 * @param  string  $referralCode
 *
 * @return boolean
 */
protected function hasUniqueReferralCode(string $referralCode) : bool
{
    // check against database to enforce uniqueness
}

您可能正在使用已过时的 PHP 版本。您可以将其移除。 - Dissident Rage
EOL 是什么意思?我正在使用 7.2.6 版本。 - Zain Shabir
终止生命周期。奇怪的是,这是7.*的一个特性。https://www.php.net/manual/en/functions.returning-values.php#functions.returning-values.type-declaration - Dissident Rage

0
if($referrelid){
    $condition = ' AND username LIKE "' . $referrelid. '" ';
    $sql = $db->getRecFrmQry("SELECT ewallet FROM " . DB_TBLPREFIX . "_mbrs WHERE 1 " . $condition . "");
    $ewallet = $sql[0]['ewallet'] + 50;
    $data =array(
        'ewallet' => $ewallet,
    );
    if (count($sql) > 0) {
         $update = $db->update(DB_TBLPREFIX . '_mbrs', $data, array('username' => $referrelid));
    }
}

当新用户使用任何推荐ID创建成功账户时,其账户将自动添加50美元。


-1
如果您希望您的推荐人代码仅为数字,那么生成唯一代码可能不是最好的选择。相反,您可以将代码保存在数据库中,从000001开始并逐步增加。
在这种情况下,您可以确保拥有唯一的代码,因为您知道所有先前的代码。
使用相同的原则,这也可以使用包含字母数字字符。但是以000AAA或类似物开头。
除了保证不冲突之外,您还可以使用is_active等列跟踪已发出的推荐人代码,并随意使它们失效。

你代码中的具体案例:

假设客户 Dave 有推荐码 illqhx。假设客户 Linda 也想要一个推荐码。

你的代码可能如下所示:

// get dave's referrer code from the database
$dave_referrer_code = 'illqhx';
$linda_referrer_code = $dave_referrer_code++;
var_dump($dave_referrer_code); // illqhx
var_dump($linda_referrer_code); // illqhz

// Do note that this code won't work, it's just an example

你实际上应该从数据库中获取具有最大ID的列,从中获取引荐者代码并递增它。
在referrer_code列上拥有unique索引将保证唯一性,因为你不能有重复的代码。
就我而言,这使得事情变得更加容易。

我已经在数据库中保存了推荐代码,列名为referral_code,我只想创建唯一的推荐代码。 - Zain Shabir
目前,你的代码只包含字母,对吗? - Andrei
是的,这只是字母。 - Zain Shabir
你应该坚持使用字母。PHP实际上也可以递增字母。所以总的来说,我的方法仍然有效。但是你可能会得到像AAAAAAAAAAAB等代码。虽然不是世界末日,但有些人可能不喜欢。这取决于你。这里的主要优点是,对于任何给定的代码,你都可以保证其唯一性,因为你可以轻松地将其与其他代码进行比较。 - Andrei
我不明白你告诉我的方法,我该怎么做。 - Zain Shabir
是的,没问题,但这不是我要找的。 - Zain Shabir

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接