2017-09-11 61 views
0

我想創建一個使用PHP頁面和MySQL數據庫來存儲細節的祕密聖誕老人系統,如果有人忘記了他們的匹配,他們可以重新請求它。使用MySQL和PHP創建一個「祕密聖誕老人」生成器

第1步:我根據數據庫中列表中的人數創建了一個隨機數生成器。

計數功能:

$maxSQL = "SELECT COUNT(id) as total FROM secretsanta"; 
$maxRS = mysqli_query($conn, $maxSQL); 
$maxQuery = mysqli_fetch_array($maxRS); 
$maxpersons = $maxQuery['total']; 

然後隨機數生成器:

$assigned = rand(1,$maxpersons); 

第2步:如果隨機數相匹配的人自己的ID,如果真再生一個新的號碼測試。

do { 
    $assigned = rand(1,$maxpersons); 
} while ($assigned==$id); 

第3步:寫配對ID的個人數據庫記錄。

$assignSQL = "UPDATE secretsanta SET assigned = '".$assigned."' WHERE secretsanta.id = ".$id; 
if (mysqli_query($conn, $assignSQL)) { 
    echo "Record updated successfully"; 
} else { 
    echo "Error updating record: " . mysqli_error($conn); 
} 

問題:現在我需要檢查,其他人都沒有分配給該人或其他一些可能錯過了和其他人會得到比別人更多。

我試圖實現一個函數,其中包含一個查詢來測試每條記錄,看看這個數字是否已經存在,並希望將它作爲一個條件添加到一段時間或做while語句?

if (!function_exists('checkRandom')){ 
    function checkRandom($funcid){ 
     $Check_SQL = "SELECT assigned FROM secretsanta ORDER BY id ASC"; 
     $Check_RES = mysqli_query($conn, $Check_SQL); 
     if (Check_RES) { 
      while ($CheckArray = mysqli_fetch_array($Check_RES, MYSQLI_ASSOC)) { 
       $CheckAsgn = $CheckArray['assigned']; 
       if ($funcid==$CheckAsgn) {return true;}else{return false;} 
      } 
     } 
    } 
} 

然後落實到了做,而這樣的說法:

do { 
    $assigned = rand(1,$maxpersons); 
} while ($assigned==$id||checkRandom($assigned)); 

至今沒有運氣...幫助..請:)

附:我知道有些網站已經這樣做了,我只是不相信他們發佈我的和家人的電子郵件地址',如果我可以自己製作我自己的私人版本。

+1

我想有一個更強大的筆記本電腦,所以我可以回答你的問題更快:-) –

+0

您的代碼很容易受到[** SQL注入**](HTTPS: //en.wikipedia.org/wiki/SQL_injection)攻擊。您應該通過[** mysqli **](https://secure.php.net/manual/en/mysqli.prepare.php)或[** PDO **](https ://secure.php.net/manual/en/pdo.prepared-statements.php)驅動程序。 [**這篇文章**](https://stackoverflow.com/questions/60174/how-can-i-prevent-sql-injection-in-php)有一些很好的例子。 –

+0

謝謝亞歷克斯,這是非常有用的信息。我從來不知道這是我能做的事情,再次感謝你,我會更多地研究這個。 – Biscuits

回答

1

使用你的方法,前幾個任務將完成沒有問題,但想象最後一個未分配的條目,它會嘗試一個隨機數只會發現與該ID的人已被分配多少次..

我會給你另一種解決問題的方法:對於你想分配聖誕老人的每個用戶,用一個WHERE子句創建一個新的SELECT語句,讓你只選擇那些尚未分配的用戶。 查看我的代碼,看看是否可以幫助你。我只是輸入這個,並沒有測試它,所以可能會有一些錯誤。

// load all unassigned users into an array 
$unassignedUsers = []; 
$query = "SELECT id, assigned FROM secretsanta WHERE assigned is NULL"; 
$res = mysqli_query($conn, $query); 
while($row = mysqli_fetch_assoc($res){ 
    $unassignedUsers[] = $row; 
} 

if(count($unassignedUsers) == 1){ 
    echo 'There is only 1 unassigned user. Therefore he cannot be matched'; 
} else { 
    // for loop for each user in DB that is not assigned yet 
    //for ($i = 1;$i <= count($unassignedUsers); $i++){ 
    $i = 0; 
    foreach($unassignedUsers as $user) 
     // if its the second-to-last iterations of the for-loop, check for legality of the last one 
     if(count($unassignedUsers) - $i == 1){ 
      $lastUserID = $unassignedUsers[count($unassignedUsers)-1]['id']; 
      $query = "SELECT id FROM secretsanta WHERE assigned is NULL AND id = ".$lastUserID; 
      $res = mysqli_query($conn, $query); 
      $rowcount = mysqli_num_rows($res); 
      if ($rowcount){ 
       // last user is still unassigned 
       $query = "UPDATE secretsanta SET assigned = '".$lastUserID."' WHERE id = ".$user['id']; 
       if(mysqli_query($conn, $query)){ 
        echo "Record with id ".$user['id']." updated successfully"; 
       } else { 
        echo "Error updating record: ".mysqli_error($conn); 
       } 
      } 
     } else { 
      // select all unassigned users 
      $unassignedIDs = []; 
      $query = "SELECT id FROM secretsanta WHERE assigned is NULL AND id <> ".$user['id']; 
      $res = mysqli_query($conn, $query); 
      while($row = mysqli_fetch_assoc($res){ 
       $unassignedIDs[] = $row['id']; 
      } 

      // get a random id from $unassignedIDs 
      $randomIndex = rand(0, count($unassignedIDs)-1); 
      $randomID = $unassignedIDs[$randomIndex]; 

      // assign $randomID to user 
      $query = "UPDATE secretsanta SET assigned = '".$randomID."' WHERE id = ".$user['id']; 
      if(mysqli_query($conn, $query)){ 
       echo "Record with id ".$user['id']." updated successfully"; 
      } else { 
       echo "Error updating record: ".mysqli_error($conn); 
      } 
     } 
     $i++; 
    } 
} 

最後編輯:重構整個代碼,以便它能夠被多次運行,只有誰分配尚未分配的新用戶。

+0

併發可能是一個問題。如果多人同時進行此操作,則可能會出現罕見的情況,其中2人被分配了相同的ID。 – manu

+0

只有當所有想參與的用戶都註冊時,該腳本才需要運行一次。不需要兩個人同時運行這個 – Cashbee

+0

這是正確的,腳本只能在任何時候運行一次,因爲這個例子它將由我來完成。如果這是作爲公開項目實施的,那麼該小組的創建者將是運行腳本的人。 – Biscuits

0

步驟1依賴於爲人們提供一組連續的ID。想想看,如果'3'離開公司並且僱用6來替換他們,會發生什麼...... 1,2,4,5,6($ maxpersons = 5)

「現在我需要檢查」 - 不,你仍然試圖通過猜測來解決問題,然後看看你的猜測是否奏效。使用總是會返回正確結果的算法。下面的方法需要添加一個類型爲float的臨時字段「序列」。

mysqli_query($conn,"UPDATE secretsanta SET sequence=RAND()"); 
$first=false; 
$prev=false; 
$all=mysqli_query($conn, "SELECT * FROM secretsanta ORDER BY sequence, id"); 
while ($r=mysqli_fetch_assoc($all)) { 
    if (false===$first) { 
     $first=$r['id']; 
    } else { 
     save_pair($prev, $r['id']); 
    } 
    $prev=$r['id']; 
} 
save_pair($prev, $first); 

(但具有更好的錯誤檢查)