【问题标题】:PHP MYSQL multiword searchPHP MYSQL 多词搜索
【发布时间】:2016-03-30 02:54:59
【问题描述】:
<?$search=$_POST['search'];
$query = $pdo->prepare("select * from tag where tag1 LIKE '%$search%' OR tag2 LIKE  '%$search%' LIMIT 0 , 10");
$query->bindValue(1, "%$search%", PDO::PARAM_STR);
$query->execute();
// Display search result
         if (!$query->rowCount() == 0) {
                echo "Search found :<br/>";

            while ($results = $query->fetch()) {

                echo "$".$results['name'];
                echo "</td></tr>";              
            }
                echo "</table>";        
        } else {
            echo 'Nothing found';
        }
?>
<form action="" method="post">
Search: <input type="text" name="search" placeholder=" Search here ... "/>
<input type="submit" value="Submit" />
</form>

我知道有很多类似的问题,但我仍然无法弄清楚。如果有人有时间,请解释我如何将explode 添加到我的搜索中,以便我可以使用超过 1 个单词进行搜索? 非常感谢您的时间。 如果我输入 1 个单词,这个脚本会搜索,在我的 case 标签中。但是如果我输入 2 个单词,它将返回 0 个结果。

【问题讨论】:

  • 按分隔符展开搜索字符串
  • sql注入高风险:$search = '%'.$search.'%'; $query = $pdo-&gt;prepare("select * from tag where tag1 LIKE :strings OR tag2 LIKE :strings LIMIT 0 , 10"); $query-&gt;bindParam(':strings', $search, PDO::PARAM_STR);
  • 仅供参考,您对 SQL 注入是安全的。通过在此处嵌入用户输入:%$search%,您允许用户直接操作您的 SQL 语句。您对bindValue 的使用不正确。考虑像这样更改您的声明:$query = $pdo-&gt;prepare("select * from tag where tag1 LIKE '%:search1%' OR tag2 LIKE '%:search2%' LIMIT 0 , 10"); $query-&gt;bindValue(":search1", $search, PDO::PARAM_STR); $query-&gt;bindValue(":search2", $search, PDO::PARAM_STR);

标签: php html mysql mysqli pdo


【解决方案1】:

注意bindValue 上的文档对第一个参数的说明:

参数标识符。

对于使用命名占位符的预准备语句,这将是:name 形式的参数名称。对于使用问号占位符的预处理语句,这将是参数的 1 索引位置。

您的 SQL 字符串中既没有 ? 占位符,也没有冒号前缀的命名占位符。相反,你 实际上将用户提供的输入直接注入到您的 SQL 中,并且容易受到 SQL 注入的攻击。 所以你应该开始使用文档中描述的占位符。

如果您想找到任何单独的单词,那么您需要扩展您的 WHERE 动态地,添加 OR 条件以匹配每个单词。使用? 占位符会更容易 在这种动态生成的 SQL 中。

另外,由于您的参数是字符串,您可以使用execute 的可选参数来传递参数数组:

输入参数

包含与正在执行的 SQL 语句中的绑定参数一样多的元素的值数组。所有值都被视为PDO::PARAM_STR

这是一些建议的代码:

// Explode to words and filter for words which are not the empty string:
$words = array_filter(explode(" ", $_POST['search']), 'strlen');
// Wrap each of the words in '%'
$words = array_map(function ($search) { return "%$search%"; }, $words);
// Add a condition for each of the words in the WHERE clause, and repeat for tag2
$sql = "select * 
        from   tag 
        where  " .
        implode(" OR ", array_fill(0, count($words), "tag1 LIKE ?")) .
        " OR " .
        implode(" OR ", array_fill(0, count($words), "tag2 LIKE ?")) .
        " LIMIT  0, 10";    
$query = $pdo->prepare($sql);
// Pass the values as string twice: once for tag1 and once for tag2
$query->execute(array_merge($words, $words));

【讨论】:

    猜你喜欢
    • 2014-11-18
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    • 1970-01-01
    相关资源
    最近更新 更多