我正在尝试使用我页面上的多个下拉列表搜索MYSQL数据库。
然而,这个搜索功能有一点点扭曲。
基本上,我需要确保所有条件(所有多个选择的dropdonw值)与项目匹配,如果匹配则显示结果!
目前,我的代码会显示结果,即使其中一个下拉值与我不想尝试的项目相匹配。
这是我的代码:
$searchList = "";
$clause = " WHERE ";//Initial clause
$sql="SELECT *
FROM `product_details`
INNER JOIN `ATTRIBUTES` ON product_details.id=ATTRIBUTES.id";//Query stub
if(isset($_POST['keyword']) && !empty($_POST['keyword'])){
foreach($_POST['keyword'] as $c){
if(!empty($c)){
$currentproduct = $_POST['product'];
$cat = $_POST['cat'];
##NOPE##$sql .= $clause."`".$c."` LIKE '%{$c}%'";
$sql .= $clause . " (ATTRIBUTES.attr LIKE BINARY '$c') AND ATTRIBUTES.sub_cat_name='$currentproduct'";
$clause = " OR ";//Change to OR after 1st WHERE
}
}
$sql .= " GROUP BY product_details.id";
//print "SQL Query: $sql<br />"; //<-- Debug SQl syntax.
// Run query outside of foreach loop so it only runs one time.
$query = mysqli_query($db_conx, $sql);
我甚至尝试删除isset
并执行if(!empty($_POST['keyword'])){
但即使其中一个下拉列表值与项目凭据匹配,我仍然会得到结果。
我不确定我在这里做错了什么,因为我认为使用if(!empty($_POST['keyword'])){
应该解决这个问题,但事实并非如此。
有人可以就此问题提出建议吗?
任何帮助将不胜感激。
编辑:我将CODE更改为以下内容并且不显示任何内容:
$clause = " WHERE ";//Initial clause
$sql="SELECT *
FROM `product_details`
INNER JOIN `ATTRIBUTES` ON product_details.id=ATTRIBUTES.id";//Query stub
$currentproduct = $_POST['product'];
$cat = $_POST['cat'];
if(!empty($_POST['keyword'])){
foreach($_POST['keyword'] as $c){
if(!empty($c)){
##NOPE##$sql .= $clause."`".$c."` LIKE '%{$c}%'";
$sql .= $clause . " (ATTRIBUTES.attr LIKE BINARY '$c') AND ATTRIBUTES.sub_cat_name='$currentproduct'";
$clause = " AND ";//Change to OR after 1st WHERE
}
}
$sql .= " GROUP BY product_details.id";
//print "SQL Query: $sql<br />"; //<-- Debug SQl syntax.
// Run query outside of foreach loop so it only runs one time.
$query = mysqli_query($db_conx, $sql);
//var_dump($query); //<-- Debug query results.
// Check that the query ran fine.
if (!$query) {
print "ERROR: " . mysqli_error($db_conx);
}
答案 0 :(得分:1)
$clause = " OR ";//Change to OR after 1st WHERE
即使1个关键字与attr字段匹配,上述OR运算符也会导致where条件选择记录。将其更改为“AND”以期望应用所有关键字。
此外,... AND ATTRIBUTES.sub_cat_name ='$ currentproduct'“标准似乎适用于所有关键字,因此该标准应该添加一次,而不是在循环的每次迭代中添加。$ currentproduct = $ _POST ['product '];行也应该在循环中移动。
编辑:反映将opreator更改为AND并且没有返回任何行。
...ATTRIBUTES.attr LIKE BINARY '$c'...
如果$ c中没有通配符,则上述标准将要求该字匹配attr字段,因为if =运算符已被使用,这不太可能发生。搜索中必须包含通配符:'%$ c%'
另外,对sql注入的一些保护也很好。
EDIT2: 如果每个属性都存储在自己的记录中,那么它会使事情变得复杂一些,因为where条件是针对单个记录而不是它们的集合进行评估的。
我会给你一个示例select命令,但你必须将它合并到你的php代码中。
select product_details.* FROM product_details INNER JOIN
(select product_details.id, count(ATTRIBUTES.id) as total
FROM `product_details`
INNER JOIN `ATTRIBUTES` ON product_details.id=ATTRIBUTES.id
WHERE ATTRIBUTES.attr in (...)
GROUP BY product_details.id
HAVING total=...) as t
on t.id=product_details.id
子查询计算产品匹配的属性数量,并消除那些,其中计数不等于通过表单提交的参数数量。外部查询获取计数匹配的那些产品详细信息。
对于in()子句中的...,您需要提供逗号分隔的'关键字列表,例如:“'computer','apple'”。在php和sztring连接中使用implode()函数来获得结果。
对于having子句中的...替换$ _POST ['keyword']数组中的关键字数量(如果它是一个数组或者只是一个值,你应该检查代码。)
但是,您应该考虑sql注入对代码的影响。