Mysqli bind_param() 没有按预期工作
Mysqli bind_param() doesnt work as expected
谁能告诉我我做错了什么?
当我执行并获取它时,我将成为正确的结果。
$message = '100';
if($stmt = $mysqli->prepare("select english from table where message=? LIMIT 1")) {
$stmt = bind_param("i", $message);
} //Return the Message in English
但是当我将语言放入变量并使用 bind_param() 时。
结果我刚得到新变量 ex.:
$message = '100';
$language = 'english';
if($stmt = $mysqli->prepare("select ? from table where message=? LIMIT 1")) {
$stmt = bind_param("si", $language, $message);
} //Returns "english"
我想问题是“$language”被绑定为 "String"。正确的类型是什么?已尝试将其更改为 blob 或 double,但没有结果。
让我们看看 bind_param
做了什么。
$stmt = $mysqli->prepare("select * from users where name=?");
$stmt->bind_param("s", "Dennis");
大致相当于
$stmt = $mysqli->prepare("select * from users where name='Dennis'");
但是,使用 bind_param 比手动向 SQL 查询中插入值要安全得多。因为手工插入值时,需要小心处理特殊字符;否则恶意构造的值可以使 SQL-parser 将部分值视为命令、table 名称、列名等,而不是值。bind_param 为您完成;使用 bind_param 你不必担心 Dennis
在插入 SQL 查询之前应该变成 'Dennis'
,但是 Dennis O'Brian
应该变成 'Dennis O\'Brian'
(不是 'Dennis O'Brian'
),NUL-character 应该变成 '[=22=]'
(不保留为 NUL 字符)。
bind_param 是 suitable 仅用于将 值 插入 SQL-查询。因为当你需要插入 column 或 table name 到 SQL-query 时,你实际上需要相反的东西——你需要将 column name 插入到 SQL-直接查询(不加任何引号等)。所以你实际上需要:
select english from table where message=... LIMIT 1
没有
select 'english' from table where message=... LIMIT 1
那么,就去做吧:
$message = '100';
$language = 'english';
$sql = "select " . $language . " from table where message=? LIMIT 1";
if($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("i", $message);
}
唯一的问题是您必须确保$language
包含有效的列名称。否则,如果用户强制通过 $language
传递不良信息,您将得到 SQL-injection.
$message = ...;
$language = ...;
...;
if(!in_array($language, array('english', 'german', 'french'), true))
$language = 'english';
$sql = "select " . $language . " from table where message=? LIMIT 1";
if($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("i", $message);
}
谁能告诉我我做错了什么? 当我执行并获取它时,我将成为正确的结果。
$message = '100';
if($stmt = $mysqli->prepare("select english from table where message=? LIMIT 1")) {
$stmt = bind_param("i", $message);
} //Return the Message in English
但是当我将语言放入变量并使用 bind_param() 时。 结果我刚得到新变量 ex.:
$message = '100';
$language = 'english';
if($stmt = $mysqli->prepare("select ? from table where message=? LIMIT 1")) {
$stmt = bind_param("si", $language, $message);
} //Returns "english"
我想问题是“$language”被绑定为 "String"。正确的类型是什么?已尝试将其更改为 blob 或 double,但没有结果。
让我们看看 bind_param
做了什么。
$stmt = $mysqli->prepare("select * from users where name=?");
$stmt->bind_param("s", "Dennis");
大致相当于
$stmt = $mysqli->prepare("select * from users where name='Dennis'");
但是,使用 bind_param 比手动向 SQL 查询中插入值要安全得多。因为手工插入值时,需要小心处理特殊字符;否则恶意构造的值可以使 SQL-parser 将部分值视为命令、table 名称、列名等,而不是值。bind_param 为您完成;使用 bind_param 你不必担心 Dennis
在插入 SQL 查询之前应该变成 'Dennis'
,但是 Dennis O'Brian
应该变成 'Dennis O\'Brian'
(不是 'Dennis O'Brian'
),NUL-character 应该变成 '[=22=]'
(不保留为 NUL 字符)。
bind_param 是 suitable 仅用于将 值 插入 SQL-查询。因为当你需要插入 column 或 table name 到 SQL-query 时,你实际上需要相反的东西——你需要将 column name 插入到 SQL-直接查询(不加任何引号等)。所以你实际上需要:
select english from table where message=... LIMIT 1
没有
select 'english' from table where message=... LIMIT 1
那么,就去做吧:
$message = '100';
$language = 'english';
$sql = "select " . $language . " from table where message=? LIMIT 1";
if($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("i", $message);
}
唯一的问题是您必须确保$language
包含有效的列名称。否则,如果用户强制通过 $language
传递不良信息,您将得到 SQL-injection.
$message = ...;
$language = ...;
...;
if(!in_array($language, array('english', 'german', 'french'), true))
$language = 'english';
$sql = "select " . $language . " from table where message=? LIMIT 1";
if($stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("i", $message);
}