【问题标题】:How to generate voucher code, check the DB if it's unique, generate new one if not如何生成优惠券代码,检查数据库是否唯一,否则生成新的
【发布时间】:2016-06-14 18:04:33
【问题描述】:

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

我的目标是创建一个优惠券代码生成器脚本,用户可以在其中输入要生成的优惠券代码的数量。

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

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

顺便提一下,优惠券代码的格式是: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 mysql loops for-loop do-while


    【解决方案1】:

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

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

    至于生成重复概率最小的随机字符串,请查看此线程:PHP random string generator

    我会生成完整长度的字符串,然后添加连字符。

    【讨论】:

    • 感谢您的建议和解决方案。我已经更新了脚本,代码肯定比我以前的要短。除了使用 MySQL 唯一约束之外,我还更新了生成凭证代码的功能。这是更新的(工作)脚本:hastebin.com/qurakiviya.bash
    【解决方案2】:

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

    我会做的是:

    1. 按顺序生成一大堆值(比如说几千个)值并将它们存储在 redis/SQL 数据库中
    2. 使用随机数索引数据库中的该记录,并在使用后从表中删除该记录

    这大大减少了所需的处理,还为您提供了一个预先确定的优惠券代码池,可用于您的应用程序中的其他目的

    【讨论】:

      【解决方案3】:

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

      最好的部分是它会在添加重复条目时出现Duplicate Entry 错误。因此您可以使用它将数据添加到 csv 。只有在没有错误时才添加它。

      但要确保唯一值不为空。

      【讨论】:

        猜你喜欢
        • 2011-06-01
        • 2013-04-22
        • 2020-08-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-07-24
        • 1970-01-01
        相关资源
        最近更新 更多