【问题标题】:multiple terms SQL with explode/implode and PHP PDO具有爆炸/内爆和 PHP PDO 的多个术语 SQL
【发布时间】:2012-02-22 20:54:17
【问题描述】:

我有一个搜索表单,希望用户搜索多个字词。我目前正在使用 PHP PDO,我仍在学习...我想知道是否有人可以告诉我我在这里做错了什么。

    $varSearch = @$_GET['dms']; 
    $varTerm = explode(" ", $varSearch);
    $termArray = array();
    foreach($varTerm as $term){
        $term = trim($term);
        if(!empty($term)){
            $termArray[] = "name LIKE '%".$term."%' OR tags LIKE '%".$term."%'";
        }
    }
    $implode = implode(' OR ', $termArray);
    $sql = $dbh->prepare("SELECT * FROM table WHERE ?");
    $sql->execute(array($implode));

【问题讨论】:

标签: php search full-text-search pdo search-engine


【解决方案1】:

如果其他人也需要这个答案...

$varSearch = @$_GET['dms']; 
$varTerm = explode(" ", $varSearch);
$termArray = array();
foreach($varTerm as $term){
    $term = trim($term);
    if(!empty($term)){
        $termArray[] = "name LIKE :term OR tags LIKE :term";
    }
}
$implode = implode(' OR ', $termArray);
$sql = $dbh->prepare("SELECT * FROM table WHERE ".$implode."");
$sql->execute(array(":term"=>"%".$term."%"));

【讨论】:

  • 您只在数据库中搜索一个词。
  • 我不是在数组中做吗?我不明白。为什么我得到一个否定...
  • 不,您正在准备一个非常长的语句,在其中重复使用完全相同的参数名称,然后将一个参数绑定到它。因为你的答案是错误的,所以你投了反对票。
  • 其实我只是检查了我的数组输出,我相信我的解决方案是正确的......
  • 说如果我输入 term1 和 term2,那么它将搜索 name LIKE term1 OR tags LIKE term1 OR name like term2 OR tags LIKE term2... 这使人们能够通过名称表和标签表搜索两个不同的术语
【解决方案2】:

您是否考虑过这样做:

$varSearch = @$_GET['dms'];
$varTerm = explode(" ", $varSearch);
$termsStringArray = array();
$termsArray = array();
foreach($varTerm as $term){
    $term = trim($term);
    if(!empty($term)) {
        array_push($termsStringArray, "name LIKE ? OR tags LIKE ? ");
        array_push($termsArray, $term);
        array_push($termsArray, $term);  // note, you can do this part differently, if you'd like
    }
}
$implodedTermsString = implode('OR ', $termsStringArray);
$sql = $dbh->prepare("SELECT * FROM biz WHERE " . $implodedTermsString);
$sql->execute(array($termsArray));

输出:

// prepare statement
SELECT * FROM biz WHERE name LIKE ? OR tags LIKE ? OR name LIKE ? OR tags LIKE ? OR name LIKE ? OR tags LIKE ? OR name LIKE ? OR tags LIKE ?

// $termsArray (for execute)
Array
(
    [0] => this
    [1] => this
    [2] => is
    [3] => is
    [4] => the
    [5] => the
    [6] => string
    [7] => string
)

基本上,尝试将数组数据与初始 SQL 查询 prepare 字符串分开。让我知道这是否适合您!

尽管如此,您仍然需要对从$_GET 变量中获取的数据进行某种检查(或清理)。 $_GET 变量可能包含任何内容...并且可能对 SQL injections 或其他不需要的问题不利。

而且,LIKE 不一定是进行此类数据库搜索的最有效方式。但是,如果您使用它(并且我过去曾将其用于搜索内容),请尝试查看:http://use-the-index-luke.com/sql/where-clause/searching-for-ranges/like-performance-tuning

【讨论】:

  • 我以为prepare对SQL注入不敏感?
  • 我一定在你写评论的时候更新了这个... :) 在数据进入数据库之前清理数据通常是好的。 (diovo.com/2008/09/sanitizing-user-data-how-and-where-to-do-it)
  • 谢谢,还有..我下面的答案不一样吗?将其放入数组中?
  • 有点像@Brad 在他后来的评论中暗示的那样,我相信你之前的答案仍然会搜索相同的 :term... 因为 :term 最终是唯一的在代码末尾键入您的数组,对吗? :) 我给出的替代答案应该遍历您正在搜索的所有术语,因为所有术语都在一个单独的数组中(termsArray )......而prepare 字符串(implodedTermsString )只使用@ 987654336@ 对于每个单独的数组值。
  • 我收到一个错误Warning: array_push() expects parameter 1 to be array,
【解决方案3】:

翻拍

$my_explode = explode(" ",$search);
$query = array();
foreach($my_explode as $string)
{
$query[] ="name LIKE '%".$string."%' OR email LIKE '%".$string."%'";
}
$implode = implode(' OR ', $query);
foreach ($db->query("SELECT * FROM _table WHERE ".$implode."") as $info)
{
    echo $info['name']."<br />";
}

安全注入,用 php 检索字母数字字符

$search = preg_replace("/[^a-zA-Z0-9]+/", "-", $_GET["text"]);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多