Как выполнить запрос LIKE, используя несколько ключевых слов из поля поиска, используя подготовленный оператор mysqli - PullRequest
0 голосов
/ 28 июня 2018

Этот вопрос похож на этот ранее заданный вопрос за исключением того, что я использую mysqli вместо PDO.

Я выполняю запрос так:

$word=preg_split('/[\s]+/',$terms);
$totalwords=count($word);

$ условия получены далее от GET

$sql="SELECT title,content FROM articles WHERE (title LIKE CONCAT('%',?,'%') OR (content LIKE CONCAT('%',?,'%'))";

for(i=1;$i<$totalwords;$i++){
  $sql.=" OR (title LIKE CONCAT('%',?,'%') OR (content LIKE CONCAT('%',?,'%'))";
}

$stmt=$conn->prepare($sql);
foreach($word as $key => $keyword){
  $term=$keyword;
  $stmt->bind_param('ss',$term,$term);
}
$stmt->execute;
$stmt->store_result;

Если я ввожу одно слово в форму поиска, я получаю правильные результаты, однако, если я ввожу более одного слова, я вообще не получаю никаких результатов.

Итак, я включил print_r($sql);, чтобы увидеть, что отправлялось в базу данных, и это то, что я получаю за один термин (который отлично работает):

SELECT title,content FROM articles WHERE (title LIKE CONCAT('%',?,'%') OR content LIKE CONCAT('%',?,'%'));

и это то, что я получаю за несколько слов (которые не дают результатов, хотя и должны):

SELECT title,content FROM articles WHERE (title LIKE CONCAT('%',?,'%') OR content LIKE CONCAT('%',?,'%')) OR (title LIKE CONCAT('%',?,'%') OR content LIKE CONCAT('%',?,'%'));

кажется, что все работает нормально, поэтому я включил свои журналы mysql и обнаружил, что запросы с одним словом отображаются, но запросы с несколькими словами отсутствуют.

Итак, я добавил print_r($stmt); и получил Commands out of sync; you can't run this command now для запросов из нескольких слов.

Что я делаю не так?

1 Ответ

0 голосов
/ 02 июля 2018

Как пользователь3783243 заявляет в комментариях выше, мои заполнители и параметры не совпадают. Поэтому, чтобы решить эту проблему, я сделал следующее (это будет неаккуратно, так как я новичок в PHP, но если кто-то сможет это почистить для меня, я получу ответ на этот вопрос).

Сначала вы должны создать строку для параметра типа (у меня все строки, так что это было легко, вы можете запустить условный оператор, если у вас разные типы). Поскольку я использую два заполнителя для каждой записи в моем SQL, каждая итерация будет включать два s.

$typeparam='';
foreach($word as $key => $value){
  $typeparam.='ss';
}

Затем создайте новый массив, чтобы соединить все типы и значения (опять же, поскольку для каждого параметра есть два заполнителя, я просто добавляю $ word дважды в массив):

$bindpars=array();

$bindpars[]=&$typeparam;
foreach($word as $key => $value){
  $bindpars[]=&$word[$key];
  $bindpars[]=&$word[$key];
}

Наконец, свяжите параметры, используя call_user_func_array:

call_user_func_array(array($stmt,'bind_param'),$bindpars);

Итак, код в моем вопросе теперь выглядит так:

$word=preg_split('/[\s]+/',$terms);
$totalwords=count($word);

$sql="SELECT title,content FROM articles WHERE (title LIKE CONCAT('%',?,'%') OR (content LIKE CONCAT('%',?,'%'))";

for(i=1;$i<$totalwords;$i++){
  $sql.=" AND (title LIKE CONCAT('%',?,'%') OR (content LIKE CONCAT('%',?,'%'))";
}

$stmt=$conn->prepare($sql);

$typeparam='';
foreach($word as $key => $value){
  $typeparam.='ss';
}

$bindpars=array();

$bindpars[]=&$typeparam;
foreach($word as $key => $value){
  $bindpars[]=&$word[$key];
  $bindpars[]=&$word[$key];
}

call_user_func_array(array($stmt,'bind_param'),$bindpars);

$stmt->execute;
$stmt->store_result;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...