PHP:在具有SQL注入预防的查询中使用IN语句时出错

PHP:在具有SQL注入预防的查询中使用IN语句时出错,php,arrays,multidimensional-array,associative-array,Php,Arrays,Multidimensional Array,Associative Array,我是PHP新手,希望有人能在这方面帮助我 我目前拥有以下PHP,它是jQuery中Ajax调用的一部分。 当手动输入ID而不是?(例如1,2,3,4,5)时,这会按预期工作,但当我使用下面的查询时,它只返回一个项,如下所示,因此我相信IN(?)和我阻止SQL注入的尝试的组合在这里不起作用 有人能告诉我我做错了什么吗? 此外,这会创建一个多维数组,我想知道这是否可以简化,因为我只需要每个项目的ID(tID)和值(content) 我的PHP: $content = implode(",", $_P

我是PHP新手,希望有人能在这方面帮助我

我目前拥有以下PHP,它是jQuery中Ajax调用的一部分。 当手动输入ID而不是?(例如1,2,3,4,5)时,这会按预期工作,但当我使用下面的查询时,它只返回一个项,如下所示,因此我相信IN(?)和我阻止SQL注入的尝试的组合在这里不起作用

有人能告诉我我做错了什么吗?
此外,这会创建一个多维数组,我想知道这是否可以简化,因为我只需要每个项目的ID(
tID
)和值(
content

我的PHP:

$content = implode(",", $_POST["content"]);  // an array containing IDs retrieved from Ajax
$languageFrm = $_POST["languageFrm"];

$stmt = $conn->prepare("SELECT tID, " . $languageFrm . " FROM TranslationsMain WHERE tID IN(?) ORDER BY tID");
$stmt->bind_param("s", $content);
$stmt->execute();
$result = $stmt->get_result();
while($arrTranslations = $result->fetch_assoc()){
    $translations[] = array("tID" => $arrTranslations["tID"], "content" => $arrTranslations[$languageFrm]);
}
var_dump($translations);
array(1) {
  [0]=>
  array(2) {
    ["tID"]=>
    int(1)
    ["content"]=>
    string(6) "Value1"
  }
}
Ajax中的当前结果:

$content = implode(",", $_POST["content"]);  // an array containing IDs retrieved from Ajax
$languageFrm = $_POST["languageFrm"];

$stmt = $conn->prepare("SELECT tID, " . $languageFrm . " FROM TranslationsMain WHERE tID IN(?) ORDER BY tID");
$stmt->bind_param("s", $content);
$stmt->execute();
$result = $stmt->get_result();
while($arrTranslations = $result->fetch_assoc()){
    $translations[] = array("tID" => $arrTranslations["tID"], "content" => $arrTranslations[$languageFrm]);
}
var_dump($translations);
array(1) {
  [0]=>
  array(2) {
    ["tID"]=>
    int(1)
    ["content"]=>
    string(6) "Value1"
  }
}
更新:
我的问题是,尽管发布的链接和当前的答案似乎引用了正确的解决方案,但我无法让其余的PHP代码正常工作,因为每当我使用其中一个建议的解决方案时,我都会遇到错误“
调用非对象上的成员函数fetch_assoc()。

非常感谢您在这方面的帮助,

Mike

您正在将字符串绑定到SQL代码中的单个参数。这意味着您的SQL将转换为
从表WHERE属性中选择一些内容(“1,2,3,4,5”)
,这显然不是您想要的

您试图做的是将多个参数动态绑定到SQL。这可以通过动态设置prepared语句中的参数数量来实现,如中所示。由于这是一个非常常见的用例,所以我在手册中添加了它作为一个通用示例


因为这里使用的是MySQLi而不是PDO,所以我将提供MySQLi等效示例

$params = $_POST["content"];

$place_holders = implode(',', array_fill(0, count($params), '?'));


$stmt = $conn->prepare("SELECT tID, " . /* no way on earth will I ever do
                                           this $languageFrm */ null .
                       " FROM TranslationsMain WHERE tID IN($place_holders) ORDER BY tID");
// substitute PDO::execute() for call_user_func_array to bind_params because MySQLi sucks
call_user_func_array([$stmt, 'bind_param'], $params);
$stmt->execute();
$result = $stmt->get_result();
while($arrTranslations = $result->fetch_assoc()){
    $translations[] = array(
                            "tID" => $arrTranslations["tID"],
                            "content" => $arrTranslations[$languageFrm],
                           );
}
var_dump($translations);

您仍然容易受到SQL注入的攻击

也请考虑您准备好的语句<强>对SQL注入 $*POST [“语言-FRM”] < /代码>行< /P>

$stmt = $conn->prepare("SELECT tID, " . $languageFrm .
        " FROM TranslationsMain WHERE tID IN(?) ORDER BY tID");

在您准备好的语句中,那个大红色突出的
$languageFRM
来自用户输入,并且是SQL代码的一部分,也就是说,使您在查询中使用参数的所有努力都变得毫无用处。

请参阅:使用一种变通方法来扩展用于参数绑定的占位符
?,,,,,,…
列表@Rizier123:谢谢-我会看一看。@mario:谢谢-我也会看一看。我看了这里提供的链接,它们似乎针对我的问题,但我仍然难以将其应用到我的查询中。非常感谢-这非常有帮助!更新:我查看了您的示例并相应地更新了我的代码,但看起来我无法使用其余的代码(即$stmt->execute();)之后的所有内容),因为这会引发错误“调用非对象上的成员函数fetch_assoc()”。你能告诉我如何调整这个吗?另外,我不确定,但在我看来,您可能必须将示例中的($place\u holders)替换为(“.$place\u holders”)?这将表明
$result
不是对象,进一步推断您对
$stmt->get\u result()
的调用失败。看见请注意,我指出的示例是针对PDO的,而您在这里使用的是
MySQLi
。要使此代码适应MySLQi,您需要使用
call\u user\u func\u array
调用
mysqlistement::bindParam()。不,这个例子是正确的,因为SQL字符串在调用prepare时包含大括号。非常感谢您的更新和解释。我按照建议应用了这个,但它不起作用。如果我如上所述使用它,那么Dreamweaver会将call_user_func_数组行标记为无效(可能是因为方括号),如果我使用数组($stmt,“bind_param”),那么Dreamweaver会接受它,但我会再次得到以下错误:“调用非对象上的成员函数fetch_assoc()”。同样的逻辑适用。这仍然意味着
$result
不是对象。如果
$result
不是告诉您
$stmt->get_result()
失败的对象。如果
$stmt->get_result()
失败,则表明它返回了
false
。因此,如果
var\u dump($result)
false
,则支持该
$stmt->get\u result()
的操作失败。现在,我将留给读者一个练习,让他们来解释为什么这个声明失败了。