如何使用mysqli预准备语句在搜索字段中使用多个关键字执行LIKE查询

时间:2018-06-28 16:57:27

标签: php search mysqli

这个问题类似于this previously asked question,除了我使用的是mysqli而不是PDO。

我这样执行查询:

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

$ terms是从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 :(得分:0)

正如user3783243在上面的注释中所述,我的占位符和参数不匹配。因此,为了解决这个问题,我做了以下工作(这是草率的,因为我是PHP的新手,但是如果有人可以为我清理它,我将为您提供答案)。

首先,您必须为type参数创建一个字符串(因为它们都是字符串,所以这很容易,如果您使用不同的类型,则可以运行条件语句)。由于我在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;