Php 在准备好的SQL语句中设置数组

Php 在准备好的SQL语句中设置数组,php,html,mysql,prepared-statement,Php,Html,Mysql,Prepared Statement,有人告诉我“没有办法使用准备好的语句将数组绑定到SQL语句”,但我已经做到了。不过,我在重新创建它时遇到了困难 我有一个更新数据库的语句: if (isset($_POST['printRow'])){ $ids = ""; foreach ($_POST['checkbox'] as $rowid) { if(!empty($ids)) $ids .= ','; $ids .= $rowid; $_SESSION['ids'] = $ids; }

有人告诉我“没有办法使用准备好的语句将数组绑定到SQL语句”,但我已经做到了。不过,我在重新创建它时遇到了困难

我有一个更新数据库的语句:

if (isset($_POST['printRow'])){
$ids = "";
foreach ($_POST['checkbox'] as $rowid)
{
        if(!empty($ids)) $ids .= ',';
        $ids .= $rowid;
        $_SESSION['ids'] = $ids;
}
}
在这里,我忘记发布工作代码:

$stmt = $conn->prepare("UPDATE just_ink SET deleted=1 WHERE ID IN( " . $ids . ")");
    $stmt->execute();
但我仍然有以下问题:

其中$id可以是一个或多个id

因此,如果我尝试获取$ids并使用它设置会话,那么问题就来了

($_SESSION['ids'] = $ids;)
在另一页上使用

在下一页中,我想使用$_SESSION['ids']选择数据

$stmt = $conn->prepare("SELECT * FROM just_ink WHERE ID IN( " . $_SESSION['ids'] . ")");
$stmt->execute();

但这不起作用。你知道为什么吗?

它不起作用,因为正如你正确地说的,你不能用准备好的语句将数组绑定到SQL语句

绑定数组的正确方法是创建一个占位符字符串(问号),然后在循环中绑定参数

假设您有一个必要的
ID
数组,称为
$checkbox
。首先,我们需要创建一个字符串,用于在查询中绑定所需的参数。如果
$复选框
有3项,我们的字符串将如下所示

$placeholder = "?,?,?";
为此,我们可以使用函数创建一个字符串,其中除最后一个元素外的每个元素都将向占位符添加
?,
部分。对于最后一个元素,我们需要连接单个问号

$placeholder = str_repeat('?,', count($checkboxes)-1).'?';
现在,我们需要形成并准备一个包含占位符的查询:

$query = 'SELECT * FROM just_ink WHERE ID IN (".$placeholder.")';
$stmt = $conn->prepare($query);
要将每个
ID
绑定到其占位符,我们使用循环中的方法:

for ($i=0; $i<count($checkboxes); $i++) {
    $stmt->bindParam($i+1, ($checkboxes[$i]); #position is 1-indexed
}
$stmt->execute();
for($i=0;$ibindParam($i+1,($checkboxes[$i]);#位置为1-indexed
}
$stmt->execute();

是否在文件开头设置了会话\u start()

你的代码最终会变成这样

$varArray = array();
$questionArray = array();
foreach ($_POST['checkbox'] as $daNumber=>$daValue) {
    $questionArray[] = "?";

    //We're declaring these as strings, if they were ints, they would be i
    $varArray[0] .= 's';

    //These must be relational variables. The ampersand is vry important.
    $varArray[] = &$_POST['checkbox'][$daNumber];
}

//comma separated series of questionmarks    
$allDaQuestions = implode(', ', $questionArray);


$query = "SELECT * FROM just_ink WHERE ID IN ($allDaQuestions)";
$stmt = $conn->prepare($query);

//Where the magic happens
call_user_func_array(array(&$stmt, 'bind_param'), $varArray);

//continue with your regularly scheduled broadcast
$stmt->execute();
//etc. 

这不是一个有准备的计划statement@Jens它是由php编写的:)(我知道,我知道)您不引用ID。此外,您不保护任何东西。预处理语句的好处是它们保护您插入数据库中的数据。这绝对不是您的情况。因为您调用
prepare()
,如果您将值直接注入SQL查询,则不会使其成为一个预先准备好的语句:使用占位符,正确地准备它,并绑定值。因此:为了连接数组的所有项,有一个很棒的函数:它叫做@Downvoter,希望您注释以指出我的错误。Downvote并不意味着answer是错误的,只是这不是一个好答案。@lolbas我无法知道管理员选择了多少ID。我已经用有效的代码更新了我的原始帖子。@Justin使用
count
函数你不需要知道
ID
的计数。至于你的“有效代码”-事实上,它可能会做你想做的事情,但你只是搞乱了使用准备好的语句的目的-你很容易受到SQL注入的攻击。与会话无关。呃?那么,如果脚本与会话无关,为什么它在查询中有一个$\ u会话?问题与会话无关。我已经在评论中给出了答案:没有引用每个id,所以mysql将尝试将每个id解释为一个列名。@Arcellas问题不在于引用
id
。我正在使用类似的查询以及我在回答中描述的方法,它不会尝试将每个id解释为一个列名。我们不知道OP的id是如何定义的。OP似乎已经消失了。