當我重新閱讀我的問題時,我想到了使用第二個準備好的語句進行更新。首先,我試圖在最初的foreach
循環中包含第二條語句,但是這個錯誤出現了,大概是因爲您一次只能打開一個以上的語句。接下來我決定將每次迭代時的值(被檢查的user_id)存儲到一個單獨的數組中,然後在關閉最初的foreach
循環和準備好的語句之後,我使用UPDATE
的新準備語句運行第二個循環,並且瞧!下面是代碼,因爲它現在看起來:
public function ban() {
$connection = Database::getConnection();
$user_id = $_POST['user'];
$reason = $_POST['banExplain'];
$update = array();
$feedback = '';
$query = "SELECT banned, user_name
FROM users
WHERE user_id = ?";
$query2 = "UPDATE users
SET banned = '1', ban_reason = ?
WHERE user_id = ?";
$stmt = $connection -> prepare($query);
$stmt2 = $connection -> prepare($query2);
if (count($user_id) > 1) {
foreach ($user_id as $value) {
$stmt -> bind_param('i', $value);
if (!$result = $stmt -> execute()) {
$feedback .= "Did not execute search.<br />";
} else {
$stmt -> bind_result($banned, $user);
$stmt -> fetch();
if ($banned == 1) {
$feedback .= $user . " is already banned.<br />";
} else {
$update["$user"] = $value; // Populate an array to pass to update loop
}
}
}
$stmt -> close();
// Run update query - $key from $update var is the user name
foreach ($update as $key => $value) {
$stmt2 -> bind_param('si', $reason, $value);
if (!$result2 = $stmt2 -> execute()){
$feedback .="Did not execute update.<br />";
} else {
$feedback .= $key . " is banned.<br />";
}
}
$stmt2 -> close();
return $feedback;
} else {
// Executes for single selection requests
$stmt -> bind_param('i', $user_id);
if (!$result = $stmt -> execute()) {
$feedback .= "Did not execute search.<br />";
} else {
$stmt -> bind_result($banned, $user);
$stmt -> fetch();
if ($banned == 1) {
$feedback .= $user . " is already banned.<br />";
} else {
$update["$user"] = $user_id;
}
}
$stmt -> close();
// Runs loop simply for the user name in the $key var
foreach ($update as $key => $value) {
$stmt2 -> bind_param('si', $reason, $value);
if (!$result2 = $stmt2 -> execute()){
$feedback .="Did not execute update.<br />";
} else {
$feedback .= $key . " is banned.<br />";
}
}
$stmt2 -> close();
return $feedback;
}
}
相當長的什麼似乎是這樣一個簡單的任務,我想的是,mysqli::multi_query
很可能還是去了解的最佳方式這個(在使用mysqli::real_escape
添加所需的安全性之後),但除了這個函數的龐大程度之外,它可以工作,並且在保持服務器請求成本最小的情況下是安全的(從我所知道的)。
我現在要採取user934258的建議,並嘗試將其分解爲更小,更容易消化和維護類功能。如果/當我完成時,我會在這裏跟進以顯示結果,希望能幫助他人擺脫同樣的困境。如果其他人有一些好的解決方案,請讓我知道。我總是試圖提高我的編碼
謝謝大家,希望這至少可以幫助其他人在相同的情況。
好吧,thanks to user934258我回去重新檢查了這個/這些方法的編碼。通過聽取他的建議,我能夠從禁止方法中刪減大約25行代碼。但是,只需要添加幾行代碼,並且通過/注入額外的參數,我就能夠使代碼多用途併入unban方法,從而移除大約77行不需要的重複代碼(unban是除了它在DB中檢查了Zero而不是One之外,並且顯示了稍微不同的響應。)對於將來可能會發現此主題的人,這裏是我的代碼的最終產品。
方法從腳本調用:
public function ban($arg) { // 0 = Unban 1 = Ban
$this -> user_id = $_POST['user']; // initially set user id as global variable
$user_id = $this -> user_id;
$this -> banReason = mysqli_real_escape_string($_POST['banExplain']);
if (!$this -> check_ban($user_id, $arg)) {
$this -> feedback .= Admin::CONNFAIL;
return $this -> feedback; // Returned connection failure on select
} elseif (!$this -> ban_user($arg)) {
$this -> feedback .= Admin::UPFAIL;
return $this -> feedback; // Returned connection failure on update
} else {
return $this -> feedback;
}
}
方法來檢查DB禁令值(S):
private function check_ban($user_id, $arg) {
$connection = Database::getConnection();
$query = "SELECT banned, user_name
FROM users
WHERE user_id = ?";
$stmt = $connection -> prepare($query);
foreach ($user_id as $value) {
$stmt -> bind_param('i', $value);
if (!$result = $stmt -> execute()) {
return FALSE;
} else {
$stmt -> bind_result($banned, $user);
$stmt -> fetch();
if ($arg == 1 && $banned == 1) {
$this -> feedback .= $user . " is already banned.<br />";
} elseif ($arg == 0 && $banned == 0) {
$this -> feedback .= $user . " is not currently banned.<br />";
} else {
$this -> update["$user"] = $value; // Populate array to be un/banned
}
}
}
$stmt -> close();
return TRUE;
}
最後的方法來更新數據庫與聯合國/禁令:
private function ban_user($arg) {
$connection = Database::getConnection();
$update = $this -> update;
$reason = $this -> banReason;
$query = "UPDATE users
SET banned = ?, ban_reason = ?
WHERE user_id = ?";
$stmt = $connection -> prepare($query);
foreach ($update as $key => $value) {
$stmt -> bind_param('isi', $arg, $reason, $value);
if (!$result = $stmt -> execute()) {
return FALSE;
} elseif ($arg == 0) {
$this -> feedback .= $key . " is unbanned.<br />";
} else {
$this -> feedback .= $key . " is banned.<br />";
}
}
$stmt -> close();
return TRUE;
}
請注意,這些方法中很少發生錯誤檢查/過濾/消毒。我有幾個原因:在腳本中檢查變量的值,我是唯一被授予這種權限的人,並且像$user_id
這樣的變量值被預填充到複選框和下拉列表中,從數據庫的價值,所以錯誤$user_id
的機會是渺茫的。
正如我在其他文章中提到的,如果任何人都可以提供更好的解決方案,我已經完成了,請讓我知道。
感謝這樣一個偉大的社區!
您的權利,代碼仍然非常程序化。發佈這個問題後,我想出了一個解決方案,雖然不是更多的OOP風格,只是一個更長的版本(請參閱我的答案回覆。)但它的工作原理。現在我會接受你的建議,看看我是否可以把它分解成更小,更多的OOP風格的功能。 – 2012-03-16 00:48:42