php - 准备好的 MySQLi 中的通配符返回错误值

标签 php mysql

有关最新信息和当前状态,请参阅本文底部

根据此类帖子的建议: Using wildcards in prepared statement - MySQLi

我已经设置了我的声明,并且它可以正常工作。但它不会返回正确的数据。

我的选择语句在 WHERE 中有这个:

 WHERE `Name` LIKE ?  order by `Name`

我的字符串设置绑定(bind),然后是实际绑定(bind)。

$whatToBind = '%'. $whatName .'%';

$stmt = $mysqli->prepare($selectStr);
$stmt->bind_param('s', $whatToBind);
$stmt->execute();

当我得到我的返回时,它会完全错过它应该匹配的记录。 就像,如果我发送“Ken L”,我会返回“Ken Linton”的记录,而不是“Ken Lawton”。如果我输入“Lawton”,我将一无所获。

这是全面的典型行为。如果我搜索电话号码字段,我会在“658”上得到返回,但在“609-658”上没有返回。

如果有人能告诉我我错过了什么,那就太好了。

显示我所指的确切示例的示例返回:

不完整: enter image description here

空的,尽管它不应该是: enter image description here

返回所有,包括本应与其他 2 一起存在的记录: enter image description here

需要回答的问题: 还有一些需要检查的地方:

Check the MySQL / PHP interaction character set is set correctly, typically with: $mysqli->set_charset("utf8mb4"); right after database connection is established.

设置为 utf8。尽管在设置之前它的行为相同。

Can you show any output from $mysqli->error ?

没有错误。只是不完整的返回

Can you show us your whole SQL query?

它包含在屏幕抓取中。虽然,这只是一个普通的字符串。而且它没有说明准备好的语句是什么样子的。

Can you show the Collation / MySQL structure of the Names column?

按照 GoDaddy 的 phpMyAdmin 都是 utf8

Can you show what the value of $whatName is right before binding?

它位于屏幕抓取的顶部。它会在其他任何事情发生之前回显出来。

此时我认为问题在于当我正在搜索的字段包含空格或其他不是字母的字符时会发生什么。不是我传递的确切内容。但更像是,一旦准备好语句,准备的内容与它正在搜索的字段中的内容不匹配。当您在空间存在之前搜索字段时,不会发生这种情况。这就是为什么“Ken”100% 的工作,但“Lawton”完全失败的原因。在空格之后。

我已经尝试了所有转换编码类型的方式。我已经尝试了连接字符串的各种方法。我得到的结果要么没有更好,要么完全打破它。

如果有人有更多想法,这个赏金还剩 21 小时。 在这一点上,我更乐意将 25 分奖励给提供最佳信息的两个家伙。奖励一个而不奖励另一个似乎不公平。

最佳答案

Please note that the details on this answer are unlikely to resolve the question on their own. With my own further testing I established that appending % or _ wildcards to strings before they are bound does not effect the way they are bound to the query.

您当前尝试做的是将数据 ($whatName) 与每侧的 SQL 指令 % 连接起来,而 Prepared Statement 解析器根本不是有这个,因为它违背了准备语句的安全目的。

因此,解决方案是您只需在插入点手动将变量连接到 LIKE 语句中,而不是之前,就像您现在所做的那样。

下面的例子会如你所愿:

$selectStr = WHERE `Name` LIKE CONCAT('%',?,'%') ORDER BY `Name`
$whatToBind = $whatName;
$stmt = $mysqli->prepare($selectStr);
$stmt->bind_param('s', $whatToBind);
$stmt->execute();

注意 dataquery 从不混合,直到准备好的语句被执行。


关于 UTF-8 和 MySQL 上的字符集的说明:

不要使用 utf8_ MySQL 字符集,因为它们是真正 UTF-8 的不完整子集,因此仍然会引发字符识别的严重问题。相反,您想使用 utf8mb4_ 字符集/排序规则/等。

字符编码可能与您的问题相关,我强烈建议您阅读 this Stack Overflow Question 上给出的优秀答案。以及使用 PHP mb_ multibyte string functions .


一些进一步的检查:

  • 检查 MySQL/PHP interaction 字符集设置是否正确,通常在数据库连接后立即使用:$mysqli->set_charset("utf8mb4");成立。

  • 你能显示 $mysqli->error 的任何输出吗?

  • 您能否向我们展示您的整个 SQL 查询?

  • 你能显示 Names 列的 Collat​​ion/MySQL 结构吗?

  • 你能在绑定(bind)之前显示 $whatName 的值吗? (虽然您的问题是有道理的,但拥有特定情况和特定结果以及预期结果的特定示例对我们进行调试非常有用。

  • 愚蠢的事情,但确保你的结果没有 LIMIT ! :-D

关于php - 准备好的 MySQLi 中的通配符返回错误值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37117311/

相关文章:

php - 解析多语言提要的最佳实践

java - 从远程服务恢复的 ListView 和大型列表

php - DOMPDF 0.5.1 - 新的服务器环境破坏了 PDF 输出格式

php - 如何将此菜单包含在我的所有 View 中? [拉维尔 5]

PHP 从多个字符串中提取相似部分

javascript - jQuery 从 HTTP 请求中获取 JSON

php - 查询数据库时收到重复的答案

mysql - 修复 "Subquery returns more than 1 row"错误

php - 使用 Delphi 进行数据库连接和选择(FIREMONKEY - iOS)

javascript - 通过curl获取数据时在新标签页(Javascript)中打开PDF