Поиск MySql с использованием предложения LIKE не работает - PullRequest
0 голосов
/ 28 ноября 2018

Я пытаюсь реализовать поиск с использованием php5 pdo и mysql.То, что я пытаюсь сделать, - это искать заданный набор ключевых слов в моей таблице «posts» и возвращать записи, которые содержат любое из заданных ключевых слов в столбце «title».Но он не возвращает никакого набора результатов, даже если я дам ключевые слова, которые, как я знаю, существуют в таблице.Я использую сопоставление 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» с использованием формы возвращает ноль строк.

1 Ответ

0 голосов
/ 28 ноября 2018

Поскольку вы используете подготовленные операторы, вам не нужны одинарные кавычки вокруг выражения.Измените ваш код, удалив эти кавычки, на

$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.атаки (а также, между прочим, против синтаксических ошибок, вызванных ошибочными / неэкранированными кавычками).


PS Если запрос когда-либо был отправлен на этот код, где вообще не было предоставлено никакого ключевого слова, то код будетсбой, поскольку предполагается, что в $keywordArray[0] всегда есть значение.Подумайте о том, чтобы изменить это, чтобы проверить, было ли предоставлено ключевое слово, или просто зациклить весь массив, и, если ключевые слова не переданы, просто не добавляйте в запрос предложение WHERE вообще.

...