【问题标题】:PHP explode and MySQL query to search in multiple columnsPHP 爆炸和 MySQL 查询在多列中搜索
【发布时间】:2012-07-17 14:09:17
【问题描述】:

我有一个表单,我希望用户输入一个或多个单词。然后这些词应该匹配 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

我想将我的搜索字符串与两列的内容进行匹配。我将如何继续?

【问题讨论】:

  • 到那时,您需要foreach 超过条款并以这种方式建立您的条件。
  • @dleiftah 你能举个例子吗?

标签: mysql forms search explode implode


【解决方案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%');

【讨论】:

  • 开始看起来不错!但是我得到Undefined variable: searchCondition
  • 尝试在$searchColumns 行之后添加$searchCondition = '';
【解决方案2】:

如果您的表格是 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

【讨论】:

    【解决方案3】:

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

    我最终通过以下方式调整了 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 子句的内容,因为我使用的是 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 或任何其他访问此主题的人(例如我)来说,这可能是一个改进的解决方案,即使是在原始帖子发布将近两年之后。

    【讨论】:

      猜你喜欢
      • 2016-03-05
      • 1970-01-01
      • 1970-01-01
      • 2015-10-14
      • 2016-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-03
      相关资源
      最近更新 更多