【问题标题】:Do not require exact search in MySQL不需要在 MySQL 中精确搜索
【发布时间】:2014-01-12 18:15:05
【问题描述】:

我正在尝试在 PHP 中创建一个不需要精确搜索的搜索功能,即如果您搜索“mar”,它将返回“mark”和“mary”。

到目前为止,我有以下查询,但它没有达到我的预期。

$query = $this->db->prepare("SELECT * FROM `visitors` WHERE `first_name` LIKE ? OR `last_name` LIKE ? OR `phone` LIKE ? OR `email` LIKE ? or `spouse` LIKE ? OR `spousephone` LIKE ? OR `spouseemail` LIKE ? OR `child1name` LIKE ? OR `child2name` LIKE ? OR `child3name` LIKE ?");

这是我创建的函数的完整代码,也许有人可以建议正确的编写方法,因为我是 PHP 和 MySQL 的菜鸟。

    public function visitor_search($search_query) {

    $query = $this->db->prepare("SELECT * FROM `visitors` WHERE `first_name` LIKE ? OR `last_name` LIKE ? OR `phone` LIKE ? OR `email` LIKE ? or `spouse` LIKE ? OR `spousephone` LIKE ? OR `spouseemail` LIKE ? OR `child1name` LIKE ? OR `child2name` LIKE ? OR `child3name` LIKE ?");

    $query->bindValue(1, $search_query);
    $query->bindValue(2, $search_query);
    $query->bindValue(3, $search_query);
    $query->bindValue(4, $search_query);
    $query->bindValue(5, $search_query);
    $query->bindValue(6, $search_query);
    $query->bindValue(7, $search_query);
    $query->bindValue(8, $search_query);
    $query->bindValue(9, $search_query);
    $query->bindValue(10, $search_query);

    try {
        $query->execute();
    } catch(PDOException $e){
        die($e->getMessage());
    }

    return $query->fetchAll();
}

【问题讨论】:

  • 您需要将每个 ? 的值包装在 %mar% 中,或者如果您只想匹配开头,则只需 mar%

标签: php mysql search pdo


【解决方案1】:

不要忘记转义特殊字符,\%_
即使您使用准备好的语句,也必须转义这些字符。
(这意味着你必须在没有准备好的语句的情况下转义\ 两次

例子:

$stmt = $pdo->prepare('SELECT * FROM table WHERE foo LIKE ? AND bar LIKE ?');
$params = array(
    '%' . addcslashes($foo, '\\_%') . '%',
    '%' . addcslashes($bar, '\\_%') . '%',
);
$stmt->execute($params);

附言

public function visitor_search($search_query) {
    $sql = "SELECT * FROM `visitors` WHERE `first_name` LIKE ? OR `last_name` LIKE ? OR `phone` LIKE ? OR `email` LIKE ? or `spouse` LIKE ? OR `spousephone` LIKE ? OR `spouseemail` LIKE ? OR `child1name` LIKE ? OR `child2name` LIKE ? OR `child3name` LIKE ?";
    $stmt = $this->db->prepare($sql);
    $params = array_fill(0, substr_count($sql, '?'), '%' . addcslashes($search_query, '\\_%') . '%');
    $stmt->execute($params);
    return $stmt->fetchAll(PDO::FETCH_ASSOC);
}

你应该在外部捕获 PDOException。

【讨论】:

    【解决方案2】:

    只要您不向输入参数添加通配符,LIKE 的行为不会自动与 = 不同。

    以下查询只会找到string 等于等于“Hello”的行:

    SELECT * FROM mytable WHERE string LIKE "Hello";
    

    以下查询将查找string 包含“Hello”的行:

    SELECT * FROM mytable WHERE string LIKE "%Hello%";
    

    由于您没有包含实际执行查询的代码,我只能假设您错过了添加那些%s。

    见:http://dev.mysql.com/doc/refman/5.1/en/string-comparison-functions.html

    【讨论】:

    • 你是对的,但在这种情况下,他正在使用参数查询。
    • 当然可以,但问题还是一样。我只是想通过使用普通 SQL 作为示例来保持简单。
    【解决方案3】:

    发生的情况是,您应该附加 % 作为后缀或前缀。 在准备好的查询中?将被替换为 var 内容,如果是文本,将添加一个 ''。为了解决这个问题,您应该在发送 var 以查询 % 字符之前添加。

    请检查:

    $search = '%'.$_GET['search'].'%';    
    $query = $this->db->prepare("SELECT * FROM `visitors` WHERE `first_name` LIKE ? OR `last_name` LIKE ? OR `phone` LIKE ? OR `email` LIKE ? or `spouse` LIKE ? OR `spousephone` LIKE ? OR `spouseemail` LIKE ? OR `child1name` LIKE ? OR `child2name` LIKE ? OR `child3name` LIKE ?");
    

    result=$query->execute(array($search,$search,$search,$search,$search,$search,$search,$search,$search,$search));

    【讨论】:

    • 为什么我收到否定的?
    • 这里有问题:'%'.$_GET['search'].'%'
    猜你喜欢
    • 2011-05-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-04
    • 1970-01-01
    • 1970-01-01
    • 2011-02-07
    相关资源
    最近更新 更多