在这里,我试图通过选择标记值过滤搜索查询。我应该在代码中进行哪些更正?
我尝试了很多方法,但是代码没有发现任何问题。
<label>Filter by:</label>
<select name="select">
<option value = "fullname">Name</option>
<option value = "username">Username</option>
</select>
<input type="text" name="keywords" style="width:20%" placeholder="Search...">
<input style="width:3%" type="submit" name="search" value="GO"/>
</div>
<br />
<?php
if (isset($_POST["search"])){
$select = $_POST['select'];
$keywords = $_POST['keywords'];
if ($query = mysqli_query($con,"SELECT * from users WHERE '%{$select}%' LIKE '%{$keywords}%' ")) {
while ($rows = mysqli_fetch_assoc($query)) {
echo "<tr>".
"<td>".$rows['fullname']."</td>".
"<td>".$rows['username']."</td>".
"</tr>";
}
}
} else {
echo "No results to display!";
echo "<br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />";
}
?>
我希望基于选择标签显示结果。当我提交表格时,它什么也没显示。
答案 0 :(得分:2)
好的,我有很多事情要评论。
$select = $_POST['select'];
$keywords = $_POST['keywords'];
if ($query = mysqli_query($con,"SELECT * from users WHERE '%{$select}%' LIKE '%{$keywords}%' ")) {
使用LIKE
谓词仅在右侧操作数上接受通配符。因此,您不需要左侧的%
通配符。
我假设您的表单选项“全名”和“用户名”应该是列名。但是,在左侧操作数'$select'
周围使用单引号会将其视为字符串,而不是列名。单引号用于SQL中的字符串或日期文字,而不用于列名或表名之类的标识符。
所以现在我们应该看到:
$select = $_POST['select'];
$keywords = $_POST['keywords'];
if ($query = mysqli_query($con,"SELECT * from users WHERE {$select} LIKE '%{$keywords}%' ")) {
但是这里存在一个安全问题,因为您不知道$_POST['select']
将始终是合法的列名。通过发送POST变量(表单中的选项之一除外),某人很容易恶作剧。当您将表单输入直接复制到SQL查询中时,这是攻击者入侵您的网站的安全载体,因为攻击者可以操纵您的SQL来执行您不想要的事情。
相反,请使用查询参数作为值,并使用白名单作为标识符。
switch ($_POST['select']) {
case 'fullname':
$select = 'fullname'; break;
case 'username':
$select = 'username'; break;
default:
trigger_error("Not a valid choice to search");
die();
}
$keywords = "%{$_POST['keywords']}%";
if ($query = mysqli_prepare($con,"SELECT * from users WHERE {$select} LIKE ?")) {
$query->bind_param("s", $keywords);
if ($query->execute()) {
$result = $query->get_result();
...loop over result...
}