MySql 使用 LIKE 子句搜索无效

MySql search using LIKE clause not working

我正在尝试使用 php5 pdo 和 mysql 执行搜索。我想要做的是在我的 table 'posts' 和 return 记录中搜索一组给定的关键字,这些记录包含列 'title' 中的任何给定关键字。但它 return 没有结果集,即使我给出了我知道 table 中存在的关键字。我使用整理 '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%';

returns 两行。但是使用 'hit fifa' 的形式搜索 returns 零行。

由于您使用的是准备好的语句,因此不需要在表达式周围加上单引号。更改您的代码,删除这些引号,以

$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 注入攻击的一种方式(顺便说一句,还可以防止错误/未转义引起的语法错误引号)。


P.S。如果在根本未提供任何关键字的情况下向此代码提交请求,则代码将崩溃,因为它假定 $keywordArray[0] 中始终有一个值。考虑修改它以验证是否提供了关键字,或者只是循环整个数组,如果没有提交关键字,则根本不向查询添加 WHERE 子句。