php mysqli预备语句LIKE

use*_*164 41 php sql mysqli sql-like

如何使用mysqli使用LIKE进行查询并获得所有结果?

这是我的代码,但它不起作用:

$param = "%{$_POST['user']}%";
$stmt = $db->prepare("SELECT id,Username FROM users WHERE Username LIKE ?");
$stmt->bind_param("s", $param);
$stmt->execute();
$stmt->bind_result($id,$username);
$stmt->fetch();
Run Code Online (Sandbox Code Playgroud)

这段代码似乎不起作用.我搜索了很多.它也可能返回超过1行.那么即使它返回超过1行,我怎样才能获得所有结果呢?

ron*_*ade 63

以下是您正确获取结果的方法

$param = "%{$_POST['user']}%";
$stmt = $db->prepare("SELECT id,Username FROM users WHERE Username LIKE ?");
$stmt->bind_param("s", $param);
$stmt->execute();
$stmt->bind_result($id,$username);

while ($stmt->fetch()) {
  echo "Id: {$id}, Username: {$username}";
}
Run Code Online (Sandbox Code Playgroud)

或者你也可以这样做:

$param = "%{$_POST['user']}%";
$stmt = $db->prepare("SELECT id,Username FROM users WHERE Username LIKE ?");
$stmt->bind_param("s", $param);
$stmt->execute();

$result = $stmt->get_result();
while ($row = $result->fetch_array(MYSQLI_NUM)) {
  foreach ($row as $r) {
    print "$r ";
  }
  print "\n";
}
Run Code Online (Sandbox Code Playgroud)

我希望你意识到我直接从这里这里的手册得到了答案,这是你应该先走的地方.

  • 为了保护OP,手册页都没有提到LIKE比较"功能" (5认同)

Mar*_*tin 32


更新

根据注释,发现LIKE通配符(_%)默认情况下不会在Paramaterised查询中进行转义,因此可能会导致意外结果.

因此,在使用"LIKE"语句时,请使用此"否定前瞻"正则表达式以确保转义这些字符:

$param = preg_replace('/(?<!\\\)([%_])/', '\\\$1',$param);
Run Code Online (Sandbox Code Playgroud)

作为上述给定答案的替代方案,您还可以使用MySQL CONCAT功能:

$stmt = $db->prepare("SELECT id,Username FROM users WHERE Username LIKE CONCAT('%',?,'%') ");
$stmt->bind_param("s", $param);
$stmt->execute();
Run Code Online (Sandbox Code Playgroud)

这意味着您不需要编辑您的$param值,但确实需要稍长的查询.

  • @MikeVorisis,准备好的语句中的`CONCAT`*注入是安全的*,但在准备好的语句中使用`LIKE`子句时应该小心谨慎.考虑一下:`$ stmt = $ db-> prepare("SELECT`customer` as`projecttion` WHERE`customername` LIKE CONCAT('cust_',?,'%');");`然后`$ key = 'J%';`(甚至`$ key ='';`),`$ stmt-> bind_param('s',$ key);`.现在`$ stmt-> execute();`将返回*ALL记录*.因此,在处理具有'LIKE'子句的Prepared语句时,您仍需要以正确的方式处理`_`和`%`.即使使用预处理语句,也需要转义为`$ key ='J \%';`. (3认同)