Php mysqli(multi)\u查询-如何在循环中执行?
在为我的新网站创建了一些函数之后,我很快意识到所有使用永久编程的include文件都无法控制,因此我决定学习并将我当前编写的函数转换为OOP类,并从mysql转换为mysqli。到目前为止,转换还不算太糟糕,但我已经实现了一个具有/需要多个查询的函数,其中一个查询是在更新数据之前检查数据的选择。到目前为止,我用事先准备好的语句写的东西很有魅力,但它只做选择。我陷入困境的地方是更新数据库的时候到了。以下是我目前掌握的情况:Php mysqli(multi)\u查询-如何在循环中执行?,php,mysql,mysqli,Php,Mysql,Mysqli,在为我的新网站创建了一些函数之后,我很快意识到所有使用永久编程的include文件都无法控制,因此我决定学习并将我当前编写的函数转换为OOP类,并从mysql转换为mysqli。到目前为止,转换还不算太糟糕,但我已经实现了一个具有/需要多个查询的函数,其中一个查询是在更新数据之前检查数据的选择。到目前为止,我用事先准备好的语句写的东西很有魅力,但它只做选择。我陷入困境的地方是更新数据库的时候到了。以下是我目前掌握的情况: public function ban() { $connection
public function ban() {
$connection = Database::getConnection();
$user_id = $_POST['user'];
$feedback = '';
$query = "SELECT banned, user_name
FROM users
WHERE user_id = ?";
$stmt = $connection -> prepare($query);
// Check for a multi-user selection on POST
if (count($user_id) > 1) {
foreach ($user_id as $value) {
$stmt -> bind_param('i', $value);
if (!$result = $stmt -> execute()) {
$feedback .= "Did not execute.";
} else {
$stmt -> bind_result($banned, $user);
$stmt -> fetch();
if ($banned == 1) {
$feedback .= $user . " is already banned.<br />";
} else {
// This is where I need the code to update the database
// with the users who aren't already banned.
}
}
}
$stmt -> close();
return $feedback;
} else {
// This is where the UPDATE will be for a single person ban
// if only one was selected on POST
}
}
在此方面的任何帮助都将不胜感激。希望我能解释清楚我需要做什么。如果没有,请告诉我。谢谢 代码示例仍然是非常程序化的 您应该有一个方法来检查用户是否被禁止,以及一个方法来禁止用户 user\u banked方法应采用user\u id并返回布尔值 ban_用户方法应包含原因和用户id 应该有另一个函数或方法执行循环 将用户id转换为数组,您可以执行一个循环 使用异常处理错误
<?php
//the model
...
public function update_users (array $user_ids)
{
$result = array();
foreach ($user_ids as $user_id) {
if (!$this->user_banned($user_id)) {
$this->ban_user($user_id, $reason);
} else {
$result[$user_id] = "already banned";
}
return $result;
}
...
//the controller
//prevent XSS, cast as integers or use filter_var or something
$user_ids = sanitize((array) $_POST['user']);
try {
$result = $obj->update_users($user_ids);
} catch (Exception $e) {
...
当我重新阅读我的问题时,我开始考虑使用第二条准备好的语句进行更新。首先,我试图在初始的foreach
循环中包含第二条语句,但出现了错误,可能是因为一次打开的语句不能超过一条。接下来我决定将每次迭代的值(正在检查的用户id)存储到一个单独的数组中,然后,在关闭初始foreach
循环和prepared语句后,我使用新的prepared语句为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;
}
检查DB ban值的方法:
private function check\u ban($user\u id,$arg){
$connection=Database::getConnection();
$query=“选择禁止,用户名”
来自用户
其中用户_id=?”;
$stmt=$connection->prepare($query);
foreach($user\u id作为$value){
$stmt->bind_参数('i',$value);
如果(!$result=$stmt->execute()){
返回FALSE;
}否则{
$stmt->bind_result($banked,$user);
$stmt->fetch();
如果($arg==1&&$banked==1){
$this->feedback.=$user.“已被禁止。
”;
}elseif($arg==0&&$banked==0){
$this->feedback.=$user.。当前未被禁止。
;
}否则{
$this->update[“$user”]=$value;//填充要取消/禁止的数组
}
}
}
$stmt->close();
返回TRUE;
}
最后是使用un/ban更新数据库的方法:
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;
}
私有函数禁止用户($arg){
$connection=Database::getConnection();
$update=$this->update;
$reason=$this->banReason;
$query=“更新用户”
设置禁止=?,禁止原因=?
其中用户_id=?”;
$stmt=$connection->prepare($query);
foreach($key=>$value更新){
$stmt->bind_参数('isi',$arg,$reason,$value);
如果(!$result=$stmt->execute()){
返回FALSE;
}elseif($arg==0){
$this->feedback.=$key.“已取消绑定。
”;
}否则{
$this->feedback.=$key.“被禁止。
”;
}
}
$stmt->close();
返回TRUE;
}
注意,在这些方法中很少发生错误检查/过滤/消毒。我有两个原因:变量的值在脚本中被选中,我是唯一被授予这样做的权限的人,像$user\u id
这样的变量的值被预先填充到复选框和下拉列表中,其中包含数据库中的精确值,因此发生错误的$user\u id
的可能性微乎其微
正如我在其他帖子中提到的,如果有人能为我所做的事情提供更好的解决方案,请让我知道
感谢这么好的社区 对,代码仍然是非常程序化的。在发布了这个问题之后,我提出了一个解决方案,虽然不是一个更OOP的风格,只是一个更长的版本(见我的回答)。但是它是有效的。不过,我现在会接受你的建议,看看是否可以将其分解为更小、更OOP风格的函数。
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;
}
}
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;
}