我正在尝试创建一个类似于此的高级搜索表单;
http://img805.imageshack.us/img805/7162/30989114.jpg
但我应该为查询撰写什么?
我知道如果只有两个文本框而不是三个文本框怎么做,那么用户的概率太高了。
$query = "SELECT * FROM server WHERE ???";
我应该为“???”
写些什么我知道如何在查询中使用AND OR,但是假设用户只填写两个文本框而一个空。如果我写这样的话;
$query = "SELECT * FROM server WHERE model='".$model."' and brand='".$brand."' and SN='".$SN.'" ";
结果将作为空集返回。我希望用户可以选择是否填写一个,两个或三个标准。如果我使用OR,结果将不准确,因为如果Model有两个具有相同名称的数据(例如:M4000)但品牌不同(例如:IBM和SUN)。如果我使用OR并且用户想要搜索M4000和SUN,它将显示两个M4000。这就是为什么它不准确。
答案 0 :(得分:4)
如果用户可以决定他想为搜索输入多少条件,并且您想要合并这些条件(只有那些实际由用户填写的条件),那么您必须动态创建SQL查询以仅包含那些字段。由用户填写的搜索。我给你举个例子。
简单搜索表单的代码可能如下所示:
$search_fields = Array(
// field name => label
'model' => 'Model',
'serialNum' => 'Serial Number',
'brand' => 'Brand Name'
);
echo "<form method=\"POST\">";
foreach ($search_fields as $field => $label) {
echo "$label: <input name=\"search[$field]\"><br>";
}
echo "<input type=\"submit\">";
echo "</form>";
这样的实际搜索代码:
if (isset($_POST['search']) && is_array($_POST['search'])) {
// escape against SQL injection
$search = array_filter($_POST['search'], 'mysql_real_escape_string');
// build SQL
$search_parts = array();
foreach ($search as $field => $value) {
if ($value) {
$search_parts[] = "$field LIKE '%$value%'";
}
}
$sql = "SELECT * FROM table WHERE " . implode(' AND ', $search_parts);
// do query here
}
else {
echo "please enter some search criteria!";
}
在上面的代码中,我们动态构建SQL字符串,仅对输入的条件进行搜索(“AND”)。
答案 1 :(得分:1)
对于熟悉mysql的人,它提供了通过正则表达式(posix样式)进行搜索的功能。我需要一种在php中搜索的高级方法,而我的后端是mysql,所以这是合乎逻辑的选择。问题是,如何根据输入构建一个完整的mysql查询?以下是我希望能够处理的查询类型:
简单的正则表达式查询如下所示:
从TABLE中选择*其中ROW regexp'[[:&lt;:]] bla [[:&gt;:]]'和ROW regexp'foo';
这将查找字符串“bla”的完全匹配,意味着不是作为子字符串,然后在某处匹配子字符串“foo”。
首先,第1项和第4项是精确的单词匹配,我希望能够通过用引号括起来来实现这一点。让我们设置必要的变量然后匹配引号:
$newq = $query; # $query is the raw query string
$qlevel = 0;
$curquery = "select * from TABLE where "; # the beginning of the query
$doneg = 0;
preg_match_all("/\"([^\"]*)\"/i", $query, $m);
$c = count($m[0]);
for ($i = 0; $i < $c; $i++) {
$temp = $m[1][$i]; # $temp is whats inside the quotes
然后我希望能够排除单词,并且用户应该能够通过用短划线( - )开始单词来实现这一点,并且对于精确的单词匹配,这必须在引号内。第二个匹配是在查询前摆脱 -
if (ereg("^-", $temp)) {
$pc = preg_match("/-([^-]*)/i", $m[1][$i], $dm);
if ($pc) {
$temp = $dm[1];
}
$doneg++;
}
现在我们将$ temp设置为与posix兼容的完全匹配,然后构建mysql查询的这一部分。
$temp = "[[:<:]]".$temp."[[:>:]]";
if ($qlevel) $curquery .= "and "; # are we nested?
$curquery .= "ROW "; # the mysql row we are searching in
if ($doneg) $curquery .= "not "; # if dash in front, do not
$curquery .= "regexp ".quote_smart($temp)." ";
$qlevel++;
$doneg = 0;
$newq = ereg_replace($m[0][$i], "", $newq);
}
变量$ newq具有搜索字符串的其余部分,减去引号中的所有内容,因此剩下的是子字符串搜索项目在2和3之下。现在我们可以通过剩下的内容并基本上做同样的事情。上方。
$s = preg_split("/\s+/", $newq, -1, PREG_SPLIT_NO_EMPTY); #whitespaces
for ($i = 0; $i < count($s); $i++) {
if (ereg("^-", $s[$i])) { # exclude
sscanf($s[$i], "-%s", $temp); # this is poor
$s[$i] = $temp;
$doneg++;
}
if ($qlevel) $curquery .= "and ";
$curquery .= "ROW "; # the mysql row we are searching in
if ($doneg) $curquery .= "not ";
$curquery .= "regexp ".quote_smart($s[$i])." ";
$qlevel++;
$doneg = 0;
}
# use $curquery here in database
变量$ curquery现在包含我们构建的mysql查询。你会注意到在这里使用quote_smart,这是来自php.net的mysql最佳实践。这是本代码中唯一提到的安全性。你需要针对输入运行自己的检查,以确保没有坏字符,我只允许使用字母数字和其他一些字符。如果没有先修复它,请不要使用此代码。
答案 2 :(得分:1)
试试此代码
<?php
$model="";
$brand="";
$serialNum="";
$model=mysql_real_escape_string($_POST['model']);
$brand=mysql_real_escape_string($_POST['brand']);
$serialNum=mysql_real_escape_string($_POST['serialNum']);
$query=" select * from server";
$where_str=" where ";
if($model == "" && $brand == "" && $serialNum == "")
{
rtrim($where_str, " whrere ");
}
else
{
if($model != "")
{
$where_str.= " model like '%$model%' AND ";
}
if($brand != "")
{
$where_str.= " brand like '%$brand%' AND ";
}
if($serialNum != "")
{
$where_str.= " serialNum like '%$serialNum%' AND ";
}
rtrim($where_str, " AND ");
}
$query.= $where_str;
$records=mysql_query($query);
?>
答案 3 :(得分:0)
您必须提供来自搜索表单的$ model,$ brand,$ serial。
$query = "SELECT * FROM `TABLE` WHERE `model` LIKE '%$model%' AND `brand` LIKE '%$brand%' AND `serial` LIKE '%$serial%'";
另外看一下mysql doc
http://dev.mysql.com/doc/refman/5.1/en/string-comparison-functions.html
答案 4 :(得分:0)
基本搜索可以这样工作:
“SELECT * FROM server WHERE column_name1 LIKE'%keyword1%'AND column_name2 LIKE'%keyword2%'.....”;
这是匹配所有参数的情况。为匹配任何一个条件,将AND更改为OR