【问题标题】:mysqli prepare() is returning a boolean true instead of a statement objectmysqli prepare() 返回布尔值 true 而不是语句对象
【发布时间】:2016-05-13 05:26:10
【问题描述】:

我在整个互联网上都看到了这个问题,但其他人的解决方案都没有解决我的错误。我有以下 PHP 代码:

  $err = false;
  $mysqli = getMysqlConnection();
  if ($stmt = $mysqli->prepare("INSERT INTO users (username, email, regtime, emailverified, type) values (?,?,?,?,?);"))
  {
      date_default_timezone_set("America/New_York");
      $dateStr = date("m-d-Y h:i:s");
      $emailverified = 0;
      $type = 0;

      $stmt->bind_param('sssii', $username, $email, $dateStr, $emailverified, $type);
      $rc = $stmt->execute();
      $err = $rc ? $err : true;

      $userId = $stmt->insert_id;    

      if ($stmt = $mysqli->prepare("INSERT INTO usercreds (user_id, username, hash) VALUES (?,?,?);") && $err === false)
      {
          //
          //right here, for some reason, $stmt is true (boolean), not an object
          //

          $stmt->bind_param('iss', $userId, $username, $hash);
          $rc = $stmt->execute();
          $err = $rc ? $err : true;
      }
      else {
        $err = true;
      }
  }

第一个查询运行没有问题,但第二个查询在调用 bind_params 时中断。我收到错误

致命错误:未捕获的错误:在布尔值上调用成员函数 bind_param()

这意味着(并且我已经确认)我第二次执行$stmt = $mysqli->prepare() 时,它返回的是布尔值而不是对象。此外,它返回 true,我觉得这很奇怪。

我已经对我的查询进行了四次检查,结果非常好且有效。然而由于某种原因,我第二次尝试准备语句时,他的 prepare 方法返回一个布尔值而不是语句对象。

另一个注意事项,在第二个 prepare() 没有输出之后回显 $mysqli->error。

我该如何解决这个问题?


事后思考:

我的部分感觉是因为我连续两次使用同一个 mysqli 对象?或者可能是因为我连续两次使用相同的语句对象?为了执行第二个查询,是否需要对其中一个对象进行某种“关闭”或“重置”?

另一个修改:

我的第二个查询有效的额外证明。我复制并粘贴它并用值替换?,在mysql工作台中执行它,它运行得很好。

INSERT INTO usercreds (user_id, username, hash) VALUES (1234567890,'testusr','hashhashhash');

【问题讨论】:

  • 在你的脚本顶部弹出这个~mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
  • 哦,问题是您通过$stmt = $mysqli->prepare(...) && $err === false$stmt 分配了一个布尔值。也许试试if (!$err && $stmt = $mysqli->prepare(...))
  • @Phil 天哪,就是这样!我将 $err 检查移到了前面,它正在工作!我什至没有想到这一点。
  • 使用我第一条评论中的这一行来使 mysqli 抛出异常,并且再也不必检查false 的方法调用结果。

标签: php mysql database mysqli return


【解决方案1】:

您的问题是由错误处理方式基本错误引起的。也就是说,除了产生错误之外,还会使您的代码膨胀。

以下是您真正需要的唯一代码:

date_default_timezone_set("America/New_York");
// below is the only line you need for the error handling
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = getMysqlConnection();

$dateStr = date("m-d-Y h:i:s");
$emailverified = 0;
$type = 0;

$stmt = $mysqli->prepare("INSERT INTO users (username, email, regtime, emailverified, type) values (?,?,?,?,?)");
$stmt->bind_param('sssii', $username, $email, $dateStr, $emailverified, $type);
$stmt->execute();
$userId = $mysqli->insert_id;

$stmt = $mysqli->prepare("INSERT INTO usercreds (user_id, username, hash) VALUES (?,?,?)");
$stmt->bind_param('iss', $userId, $username, $hash);
$stmt->execute();

剩下的取决于你在出错时要做什么。

【讨论】:

    【解决方案2】:

    您将$mysqli->prepare(..) && $err === false 的结果分配给$stmt。那是一个布尔表达式。您需要以下任一变体:

    if (($stmt = $mysqli->prepare(...)) && $err === false)
    if ($err === false && $stmt = $mysqli->prepare(...))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-20
      • 2012-08-16
      • 2010-11-16
      • 1970-01-01
      • 2012-11-16
      • 2017-04-22
      • 2020-02-13
      • 1970-01-01
      相关资源
      最近更新 更多