我正在尝试使用 php5 pdo 和 mysql 实现搜索。我想做的是在表“帖子”中搜索给定的关键字集,并返回包含“标题”列中任何给定关键字的记录。但即使我给出了我知道表中存在的关键字,它也不会返回结果集。我使用排序规则“utf8mb4_unicode_ci”。这是我的代码:
<?php
if($_SERVER['REQUEST_METHOD']=='POST'){
$charset="utf8mb4";
$dsn="mysql:host=$host;dbname=$db;charset=$charset";
$opt=[ PDO::ATTR_DEFAULT_FETCH_MODE=>PDO::FETCH_ASSOC,
PDO::ATTR_ERRMODE=>PDO::ERRMODE_EXCEPTION];
$pdo=new PDO($dsn,$user,$pass,$opt);
$keywords=$_POST['keywords'];
$keywordArray=explode(' ',$keywords);
$n=count($keywordArray);
$query="SELECT * FROM posts WHERE title LIKE ?";
$keywordArray[0]="'%".$keywordArray[0]."%'";
for($i=1;$i<$n;$i++){
$keywordArray[$i]="'%".$keywordArray[$i]."%'";
$query=$query." OR title LIKE ?";
}
$query=$query." LIMIT 50;";
echo $query;
$stmt=$pdo->prepare($query);
$stmt->execute($keywordArray);
$res=$stmt->fetchAll();
echo "<br><h1>SEARCH RESULTS:</h1><br><ul>";
if($res){
foreach($res as $row){
echo "<li>".$row['date']."<a href=\"viewpost.php?postid=".$row['id']."\">".$row['title']."</a></li><br>";
}
}
else{
echo "<h2 style=\"color:red;\">No results!</h2>";
}
echo "</ul></div>";
}
?>
它在控制台内工作。
SELECT * FROM posts WHERE title LIKE '%hit%' OR title LIKE '%fifa%';
返回两行。但使用表单搜索“hit fifa”会返回零行。
最佳答案
由于您使用的是准备好的语句,因此您的表达式不需要单引号。更改您的代码,删除这些引号,以
$query="SELECT * FROM posts WHERE title LIKE ?";
$keywordArray[0]="%".$keywordArray[0]."%";
for($i=1;$i<$n;$i++){
$keywordArray[$i]="%".$keywordArray[$i]."%";
$query.=" OR title LIKE ?";
}
它将引号视为参数内值的一部分。所以你最终会得到类似的 SQL
SELECT * FROM posts WHERE title LIKE '\'%Something%\''
显然这不会匹配,因为在大多数情况下,数据库中的值在开头和结尾不会有单引号。
经过更改,它应该转换为这样的 SQL
SELECT * FROM posts WHERE title LIKE '%Something%'
这是因为参数化过程会自动为您处理引用和转义作业 - 这是防止 SQL 注入(inject)攻击的一种方式(顺便说一句,也可以防止由错误/未转义的引号引起的语法错误)。
<小时/>附注如果向此代码提交请求时根本没有提供任何关键字,那么该代码将会崩溃,因为它假定 $keywordArray[0]
中始终有一个值。考虑修改此设置以验证是否提供了关键字,或者只是循环整个数组,如果没有提交关键字,则根本不向查询添加 WHERE 子句。
关于php - 使用 LIKE 子句的 MySql 搜索不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53521814/