PHP:在具有SQL注入预防的查询中使用IN语句时出错
我是PHP新手,希望有人能在这方面帮助我 我目前拥有以下PHP,它是jQuery中Ajax调用的一部分。 当手动输入ID而不是?(例如1,2,3,4,5)时,这会按预期工作,但当我使用下面的查询时,它只返回一个项,如下所示,因此我相信IN(?)和我阻止SQL注入的尝试的组合在这里不起作用 有人能告诉我我做错了什么吗?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
此外,这会创建一个多维数组,我想知道这是否可以简化,因为我只需要每个项目的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()
的操作失败。现在,我将留给读者一个练习,让他们来解释为什么这个声明失败了。