如果名称中有撇号,我如何在表格中搜索名称?
如果我在搜索框中插入名称为Ender's Game
的撇号,则会出错。
我已经尝试过在stackoverflow上提供的解决方案,但我无法解决这个问题。
这是我的代码:
$string1 = $_GET['name'];
$quer = "SELECT * FROM info WHERE name = '$string1'";
$q = mysqli_query($conn, $quer);
如果$_GET['name']
中有撇号,则会显示错误。
我该如何解决这个问题?
答案 0 :(得分:4)
该表单中的代码容易受SQL injection攻击。请改用mysqli::prepare:
$string1 = $_GET['name'];
$quer = "SELECT * FROM info WHERE name = ?";
$stmt = $conn->prepare($quer);
$stmt->bind_param('s', $string1);
$stmt->execute();
$stmt->bind_result($result);
$stmt->fetch();
$stmt->close();
var_export($result);
如果您正在调整传统的,不安全的代码,使用mysqli_real_escape_string可能会更快。这应该作为最后的手段保留,但如果你需要它,它就在那里,它比正则表达式更好。
答案 1 :(得分:2)
您可以期望从知识渊博的StackOverflow志愿者那里反复听到的最佳实践是使用准备好的语句来确保查询的安全性和可靠性。
对于您的情况,我建议使用以下代码段,该代码段不仅可以安全地执行SELECT
查询,而且可以在整个过程中提供信息丰富的诊断/调试检查点,并允许您处理结果集-以多维表示关联数组。
$_GET['name'] = "vinay's name";
$string1 = $_GET['name'];
if (!$conn = new mysqli("host", "user", "pass", "db")) {
echo "Database Connection Error: " , $conn->connect_error; // do not show this to public
} elseif (!$stmt = $conn->prepare("SELECT * FROM info WHERE name = ?")) {
echo "Prepare Syntax Error: " , $conn->error; // do not show this to public
} elseif (!$stmt->bind_param("s", $string1) || !$stmt->execute()) {
echo "Statement Error: " , $stmt->error; // do not show this to public
}else{
$result = $stmt->get_result();
while($row = $result->fetch_array(MYSQLI_ASSOC)){
var_export($row); // do what you like here
}
}
需要注意的重要一点是,如果$stmt->bind_result($result)
表包含多个列,则使用$result = NULL
(就像Zenexer的回答一样)将不起作用(生成info
)(我认为它将只处理一栏,但我没有测试);由于SELECT *
中所选列的数量与指定变量的数量之间不平衡,因此会生成警告。
警告:mysqli_stmt :: bind_result():绑定变量的数量与准备好的语句中的字段数量不匹配
如果您想享受显式绑定结果变量的好处,则应在SELECT
子句中指定所需的列,如下所示:
if (!$conn = new mysqli("host", "user", "pass", "db")) {
echo "Database Connection Error: " , $conn->connect_error; // do not show this to public
} elseif (!$stmt = $conn->prepare("SELECT id FROM info WHERE name = ?")) {
echo "Prepare Syntax Error: " , $conn->error; // do not show this to public
} else {
if (!$stmt->bind_param("s", $string1) || !$stmt->execute() || !$stmt->bind_result($id)) {
echo "Statement Error: " , $stmt->error; // do not show this to public
} else {
while ($stmt->fetch()) {
echo "<div>$id</div>";
}
}
$stmt->close();
}