Php 如何生成凭证代码,检查数据库是否唯一,如果不唯一,则生成新的凭证代码

Php 如何生成凭证代码,检查数据库是否唯一,如果不唯一,则生成新的凭证代码,php,mysql,loops,for-loop,do-while,Php,Mysql,Loops,For Loop,Do While,我的脚本中有一个循环问题。我花了很多时间试图解决它,但我仍然不知道如何解决这个问题。我需要你的帮助和建议 我的目标是创建一个凭证代码生成器脚本,用户在其中输入要生成的凭证代码的数量 然后,脚本将在数据库表中生成所需数量的凭证,并检查每个凭证代码是否唯一-如果不唯一,将生成新的凭证代码,脚本将继续执行,直到保存所有凭证 问题是,如果数据库中已经存在凭证,则需要生成新凭证。如果新生成的凭证代码已存在于数据库中,则需要再次检查该代码;如果该代码是唯一的,则将其保存到数据库中;如果不存在,则该过程将再次

我的脚本中有一个循环问题。我花了很多时间试图解决它,但我仍然不知道如何解决这个问题。我需要你的帮助和建议

我的目标是创建一个凭证代码生成器脚本,用户在其中输入要生成的凭证代码的数量

然后,脚本将在数据库表中生成所需数量的凭证,并检查每个凭证代码是否唯一-如果不唯一,将生成新的凭证代码,脚本将继续执行,直到保存所有凭证

问题是,如果数据库中已经存在凭证,则需要生成新凭证。如果新生成的凭证代码已存在于数据库中,则需要再次检查该代码;如果该代码是唯一的,则将其保存到数据库中;如果不存在,则该过程将再次进行。这就是循环问题所在。我希望你明白我的意思

顺便说一下,凭证代码的格式是:仅XXXX-XXXX-XXXX大写字母

以下是我目前掌握的代码:

include 'conn.php';

function WriteCSV($flname,$values) {
    $Filename = "./vouchers/$flname.csv";
    $fh = fopen($Filename, 'a') or die("can't open file");
    $filecontent = $values;
    $filecontent .= PHP_EOL;
    fwrite($fh,$filecontent);
    fclose($fh);
}

function generateCode(){
    $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    $res = "";
    for ($i = 0; $i < 4; $i++) {
        $res .= $chars[mt_rand(0, strlen($chars)-1)];
    }
  return $res;
}

function generateVCode(){
    $c1 = generateCode();
    $c2 = generateCode();
    $c3 = generateCode();
    $voucher = "$c1-$c2-$c3";

    return $voucher;
}

function searchDB($con, $voucher){
    $rs = mysqli_query($con,"SELECT count(*) AS cnt FROM vouchers WHERE vouchercode = '$voucher'");
    $row = mysqli_fetch_assoc($rs);
    $cnt = $row['cnt'];

    if($cnt > 0){
        return '1';
    } else {
        return '0';
    }
}

function checkVoucher($con, $voucher, $vsource, $expiry, $today, $vnum, $vprice){

    $dbres = searchDB($con, $voucher);

    if($dbres == '1'){ //voucher found in db
        $val = '0';
        $voucher = generateVCode(); //generate a new voucher
        checkVoucher($con, $voucher, $vsource, $expiry, $today, $vnum, $vprice); //repeat the process
    } else { // voucher is unique
        mysqli_query($con, "INSERT INTO vouchers (vouchercode, source, price, expires, generated) VALUES ('$voucher', '$vsource', '$vprice', '$expiry', '$today')");
        $flname = "$vsource - ".date('d M Y')." ($vnum vouchers)";
        WriteCSV($flname,$voucher);

        $val = '1';
    }

    return $val;
}

$vnum = $_POST['vouchernum'];
$vsource = $_POST['source'];
$vprice = $_POST['amt'];
$expdate = $_POST['expdate'];
$expiry = $_POST['voucherexpiry'];
$today = date('Y-m-d');
$expconv = date('Y-m-d',strtotime("$expiry"));
$expfive = date('Y-m-d',strtotime("$expiry +5 years"));

for ($x = 1; $x <= $vnum; $x++) {
    $vouchercode = generateVCode();

    if($expdate == "no"){
        $expiry = $expfive;
    } else {
        $expiry = $expconv;
    }

    do {

        $result = checkVoucher($con, $vouchercode, $vsource, $expiry, $today, $vnum, $vprice);

    } while ($result != '1');

    header("location: index.php?s=1");
}
顺便说一下,如果您对如何更轻松地生成凭证代码有任何建议,请随时与我们分享

我认为这里的问题是do while语句或checkVoucher函数


我非常感谢你的帮助和建议。谢谢。

我会更轻松一些。将表中的凭证列设置为唯一。在PHP端生成代码,执行插入操作,在错误回调函数调用中生成新代码

基本上,这将自循环,直到插入。然后在成功回调中将其添加到显示中。所有这些都被包装在一个while循环中。一旦你拿到5分,打破循环

要生成重复机会最小的随机字符串,请检查此线程:


我会生成全长字符串,然后只添加连字符。

使用这种方法生成随机唯一数据,所需的处理量会随着生成的代码越来越多而成比例增加

我要做的是:

生成一大堆值,比如说按顺序生成几千个值,并将它们存储在redis/SQL数据库中 使用随机数在数据库中索引该记录,并在使用该记录后将其从表中删除 这大大减少了所需的处理,还为您提供了一个预定义的凭证代码池,可用于应用程序中的其他用途

Mysql唯一约束可能是您正在寻找的解决方案。它确保值始终是唯一的。它就像主键。但与主键不同,表可以有多个唯一值。 这里是w3school的链接,解释了这一点 www.w3schools.com/sql/sql\u unique.asp

最好的部分是,当添加重复条目时,它将重新生成重复条目错误。因此,您可以使用它将数据添加到csv。只有在没有错误时才添加它


但请确保唯一值不为null。

谢谢您的建议和解决方案。我已经更新了脚本,代码肯定比上一个短。除了使用MySQL唯一约束外,我还更新了生成凭证代码的函数。以下是更新后的工作脚本: