Php 如何使用mysqli prepared语句使用搜索字段中的多个关键字执行LIKE查询

Php 如何使用mysqli prepared语句使用搜索字段中的多个关键字执行LIKE查询,php,search,mysqli,Php,Search,Mysqli,这个问题与类似,只是我使用的是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<$to

这个问题与类似,只是我使用的是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;
这就是我从多个单词中得到的结果(即使应该也不会返回结果):

看起来一切正常,所以我打开mysql日志,发现出现了单词查询,但没有多词查询

所以我添加了
print\r($stmt)和我得到的
命令不同步;现在无法对多词查询运行此命令


我做错了什么?

正如用户3783243在上面的评论中所述,我的占位符和参数不匹配。所以为了解决这个问题,我做了以下工作(这将是草率的,因为我是PHP新手,但如果有人能帮我清理一下,我会给出答案)

首先,您必须为type参数创建一个字符串(我的都是字符串,所以这很简单,如果您有不同的类型,您可以运行一个条件语句)。由于我在SQL中为每个条目使用了两个占位符,因此每次迭代将包括两个
s

$typeparam='';
foreach($word as $key => $value){
  $typeparam.='ss';
}
然后创建一个新数组,将类型和值放在一起(同样,因为每个参数都有两个占位符,所以我只需在数组中添加两次$word):

最后,使用
call\u user\u func\u数组
绑定参数:

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;
$word=preg_split('/[\s]+/',$terms);
$totalwords=计数($word);
$sql=“选择文章的标题和内容,其中(标题如CONCAT('%',?,'%')或(内容如CONCAT('%',?,'%'))”;
对于(i=1;$iprepare($sql);
$typeparam='';
foreach($word作为$key=>$value){
$typeparam.='ss';
}
$bindpars=array();
$bindpars[]=&$typeparam;
foreach($word作为$key=>$value){
$bindpars[]=&$word[$key];
$bindpars[]=&$word[$key];
}
调用_user_func_数组(数组($stmt,'bind_param'),$bindpars);
$stmt->execute;
$stmt->store\u结果;

你可以做
CONCAT(标题,,,内容),比如CONCAT(“%”,?,“%”)
那么您只需要一个绑定,而不是两个。我希望出现一条关于占位符数量与参数数量不匹配的错误消息。上一个问题是使用支持命名参数的PDO。Mysqli,IMO,在绑定方式上制造了麻烦。不相关,但我不会使用
$term
变量,只使用 $keyword
…或do
=>$term
@user3783243感谢您指出绑定参数与占位符不匹配。我根本没有注意到这一点。我在下面提供了一个解决方案,因为还没有提供。如果该注释解决了您的问题,我可以将其移至答案。我不确定它是否会/不会,以及我没有测试,听起来不错。
$bindpars=array();

$bindpars[]=&$typeparam;
foreach($word as $key => $value){
  $bindpars[]=&$word[$key];
  $bindpars[]=&$word[$key];
}
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;