【问题标题】:php - mysqli works but pdo doesn'tphp - mysqli 有效,但 pdo 无效
【发布时间】:2023-04-02 15:01:01
【问题描述】:

我正在尝试切换到 pdo 并获得了成功,但我的最新功能无法正常工作。但是,当我恢复到 mysqli 时,它很好。我确定我错过了什么,但是什么??

不工作的 PDO:

$db = db_pdo();
$query = $db->prepare("select * from locks_for_sale where type_3=':search'");
$query->bindParam(":search", $sub_items[3]);
$query->execute();

if (!$result=$query->fetch()) {
    $print .= "<tr><td>&nbsp;</td><td><h3>No products currently available.</h3></td></tr>\n";
}

else {
    other code

请注意:
包含函数 db_​​pdo。
$sub_items[3] 是一个字符串。

工作 mysqli:

$db = db_conn();
$sql = "select * from locks_for_sale where type_3='".$sub_items[3]."'";
$query = $db->query($sql);

if (!$query->fetch_assoc()) {
    $print .= "<tr><td>&nbsp;</td><td><h3>No products currently available.</h3></td></tr>\n";
}

else {
    other code

再次包含 db_conn。

我知道此查询的结果是返回 2 个项目,但 pdo 版本显示 !$result。

提前致谢。

【问题讨论】:

  • var_dump($query-&gt;errorInfo() 说什么?返回 false 表示错误,所以让 PDO 准确告诉您错误是什么。
  • @Marc B 输出为array(3) { [0]=&gt; string(5) "00000" [1]=&gt; NULL [2]=&gt; NULL } array(3) { [0]=&gt; string(5) "00000" [1]=&gt; NULL [2]=&gt; NULL }

标签: php pdo mysqli


【解决方案1】:

:search 参数中删除引号:

$query = $db->prepare("select * from locks_for_sale where type_3=:search");
//--------------------------------------------------------------^^^^^^^^^^

如果被引用,它将被视为文字字符串':search',并且您将因绑定错误数量的参数而导致错误。

如果您不熟悉预准备语句,请尽量不要将它们视为等同于将变量放入 SQL 字符串中,就像您在连接或插值变量时所做的那样。相反,您将参数值直接传递到数据库引擎,数据库引擎将相应地将它们放入查询中。用适当的引用构造一个有效的语句成为 RDBMS 的责任。

【讨论】:

  • 当我按照你说的做时,屏幕上什么也没有,这让我认为问题可能在我的代码中更进一步。说了这么多,为什么mysqli能工作而pdo不能呢?
  • MySQLi 之所以有效,是因为您没有使用准备好的语句,而是将值直接插入到 SQL 字符串中。这真的是一种不同的东西。 var_dump($result) 看看你从 fetch 调用中得到了什么。
  • 我的 PDO 代码由于引号而无法正常工作,就像你说的那样,但是在我取消引用后整个脚本失败了,因为后来的函数正在使用 mysqli。我没有意识到,因为 php.ini 没有设置为在浏览器中回显错误,我只通过命令行看到了它。一个基本的设置错误真的。谢谢。
【解决方案2】:

鉴于您的00000 错误代码,这实际上意味着查询成功。问题在于您的获取逻辑:

if (!$query->fetch_assoc()) {
    ^--- remove

如果获取成功,调用将返回非假,即真。然后你用! 反转它并将其变为false,导致other code 运行。

【讨论】:

  • 我们知道查询的结果是真的,不管它的值是什么。当然,对此的合法测试是询问查询的结果是否不正确?这就是为什么我将! 放在开头以从任何错误或不正确的查询中继续前进。如果它是真的,它应该是并且它在mysqli中,那么代码应该处理代码的else {部分,不是吗?
  • 当然,但问题在于您的代码排序。如果你颠倒 if() 测试的意义,你必须颠倒真/假块的顺序。您的代码归结为“如果查询失败,则做成功的事情,否则做失败的事情”。
  • 感谢您对错误检查/代码排序的回复和想法。我一直认为获取是正确的,但很高兴用 errorInfo 确认它,这是我将来会做的事情。谢谢。
【解决方案3】:

试试 bindValue (http://www.php.net/manual/en/pdostatement.bindvalue.php)

<?php
/* Execute a prepared statement by binding PHP variables */
$calories = 150;
$colour = 'red';
$sth = $dbh->prepare('SELECT name, colour, calories
    FROM fruit
    WHERE calories < :calories AND colour = :colour');
$sth->bindValue(':calories', $calories, PDO::PARAM_INT);
$sth->bindValue(':colour', $colour, PDO::PARAM_STR);
$sth->execute();
?>

另请参阅: What is the difference between bindParam and bindValue?

【讨论】:

  • 是的,虽然我没有指定 PARAM::STR 位,但也没有用,所以我现在就试试。
猜你喜欢
  • 1970-01-01
  • 2011-01-02
  • 2021-02-21
  • 2013-12-23
  • 1970-01-01
  • 2018-12-01
  • 1970-01-01
  • 2013-07-28
  • 2013-01-24
相关资源
最近更新 更多