PHP爆炸和MySQL查询在多列中搜索

时间:2012-07-18 13:56:15

标签: mysql forms search explode implode

我有一个表单,我希望用户输入一个或多个单词。这些单词应匹配MySQL数据库中的多列。

我已经开始构建一些代码但是我被卡住了。

<?php
  $term = $_SESSION['session_searchstring']; //Let's say that session is John Doe
  $searchterm = explode(' ',$term);

  $searchFieldName = "name";
  $searchCondition = "$searchFieldName LIKE '%" . implode("%' OR $searchFieldName LIKE '%", $searchterm) . "%'";

  $sql = "SELECT * FROM students WHERE $searchCondition;";

  echo $sql; //Echo to test what mysql_query would look like

?>

上面的代码将输出:

SELECT * FROM students WHERE name LIKE '%John%' OR name LIKE '%Doe%'; 

问题是我想搜索多个列($searchFieldName)。我有例如

customer_firstname
customer_lastname

我希望将我的searchstring与两列的内容相匹配。我将如何继续?

3 个答案:

答案 0 :(得分:1)

如果您的表格属于MyIsam类型,或者您可以将其转换为MyIsam,请使用MySQL Fulltext Search。如果没有,无论如何,你可以构建像

这样的长查询
SELECT * FROM students WHERE name LIKE '%John%' OR name LIKE '%Doe%' OR lastname LIKE "%John%" OR lastname LIKE "%Doe%"

或将你的列联合起来仅用于搜索(但这两者都不是首选)。 另一个好方法是使用全文搜索引擎,如Sphinx

答案 1 :(得分:1)

也许

  $term = $_SESSION['session_searchstring']; //Let's say that session is John Doe
  $searchterm = explode(' ',$term);

  $searchColumns = array("customer_firstname","customer_lastname");

  for($i = 0; $i < count($searchColumns); $i++)
    {
        $searchFieldName = $searchColumns[$i];
        $searchCondition .= "($searchFieldName LIKE '%" . implode("%' OR $searchFieldName LIKE '%", $searchterm) . "%')";
        if($i+1 < count($searchColumns)) $searchCondition .= " OR ";
     }

  $sql = "SELECT * FROM students WHERE $searchCondition;";

  echo $sql; //Echo to test what mysql_query would look like

可生产

SELECT * FROM students WHERE (customer_firstname LIKE '%John%' OR customer_firstname LIKE '%Doe%') OR (customer_lastname LIKE '%John%' OR customer_lastname LIKE '%Doe%');

答案 2 :(得分:0)

在我的情况下,我需要所有搜索词组/术语至少匹配一列,没有搜索词组/词语可能不匹配。

我最终以下列方式从Kermit调整了示例:

public function getRawWhereFilterForColumns($filter, $search_columns)
{
  $search_terms = explode(' ', $filter);
  $search_condition = "";

  for ($i = 0; $i < count($search_terms); $i++) {
    $term = $search_terms[$i];

    for ($j = 0; $j < count($search_columns); $j++) {
      if ($j == 0) $search_condition .= "(";
      $search_field_name = $search_columns[$j];
      $search_condition .= "$search_field_name LIKE '%" . $term . "%'";
      if ($j + 1 < count($search_columns)) $search_condition .= " OR ";
      if ($j + 1 == count($search_columns)) $search_condition .= ")";
    }
    if ($i + 1 < count($search_terms)) $search_condition .= " AND ";
  }
  return $search_condition;
}

我只需要Where-clause的内容,因为我使用Laravel并且可以将它放入rawWhere方法。

<强>用法:

$search_condition = $this->getRawWhereFilterForColumns
    ("John Doe", array("column1", "column2"));
产生

    (column1 LIKE '%John%' OR column2 LIKE '%John%') 
AND (column1 LIKE '%Doe%' OR column2 LIKE '%Doe%')

最后你以任何适合自己的方式使用这个$ search_condition,例如:

 $sql = "SELECT * FROM students WHERE $search_condition;";

或者在我的Laravel案例中:

 $modelInstances = Model::whereRaw
     ($search_condition)->paginate(self::ITEMS_PER_PAGE);

对于David或任何其他访问此帖子的人来说,这可能是一个改进的解决方案,就像我一样,即使它在原帖后差不多两年。