2016-03-02 24 views
2

我的腳本中存在循環問題。我花了很多時間來修復它,但我仍然不知道如何解決這個問題。我需要你的幫助和建議。如何生成憑證代碼,檢查數據庫是否唯一,如果不是,生成新的憑證

我的目標是創建一個憑證代碼生成器腳本,用戶輸入要生成的憑證代碼的數量。

然後,腳本將在數據庫表中生成所需數量的憑證,並且將檢查每個憑證代碼是否唯一 - 如果不是,將生成新的憑證代碼,腳本將繼續執行,直到所有憑證被保存。

問題是,如果憑證已存在於數據庫中,則需要生成新憑證。如果新生成的憑證代碼已經存在於數據庫中,則需要再次進行檢查,如果它是唯一的,則會將其保存到數據庫中,否則該流程將再次進行。這是循環問題所在。我希望你明白我的意思。

順便說一句,該優惠券代碼的格式如下: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()函數中。

我真的很感激你的幫助和建議。謝謝。

回答

2

我會完全容易。將表格中的憑證列設置爲唯一。生成一個代碼PHP端,做你的插入,在錯誤回調函數調用中生成一個新的代碼。

基本上,這將自循環直到插入。然後在您的成功回調中將其添加到您的顯示器。所有這些都包含在一個while循環中。一旦你得到你的5,打破循環。

至於產生了重複的機率很少隨機字符串,檢查此線程:PHP random string generator

我會產生全長字符串,然後只需添加您的連字符。

+1

謝謝您的建議和解決方案。我已經更新了腳本,代碼比我之前的代碼更短。除了使用MySQL唯一約束外,我還更新了生成憑證代碼的功能。以下是更新的(工作)腳本:http://hastebin.com/qurakiviya.bash – maikelsabido

+0

正確的URL:http://hastebin.com/jehelidiqa.bash – maikelsabido

1

使用此方法生成隨機唯一數據,隨着生成越來越多的代碼,所需的處理量將成比例地增加。

我會做的,而不是爲:

  1. 生成一大堆值(可以說幾千)值順序,並將其隨機數存儲在Redis的/ SQL數據庫
  2. 使用索引在數據庫中的記錄,並從表中刪除的記錄,一旦它已被用於

這減少了所需的處理很大,也給你的優惠券代碼預先確定的池可能是在其它目的你的應用程序

1

Mysql unique約束可能是您正在尋找的解決方案。它確保值始終是唯一的。這就像主鍵。但與主鍵不同,表格可以具有多個唯一值。 這裏是w3school解釋這個 www.w3schools.com/sql/sql_unique.asp

最好的部分是添加一個重複的條目時,它會genrerate一個Duplicate Entry錯誤的鏈接。因此您可以使用它將數據添加到csv。只有在沒有錯誤時才添加它。

但請確保唯一值不爲空。

相關問題