【问题标题】:Trying to access array offset on value of type bool尝试访问 bool 类型值的数组偏移量
【发布时间】:2020-05-20 07:53:22
【问题描述】:
$query = $pdo -> prepare("SELECT * FROM Users WHERE Username =:Username");
$query->bindParam(':Username', $name);
$query->execute();

$nameRes = $query->fetch(PDO::FETCH_ASSOC);
if ($nameRes['Username']==$_POST['username']) {
    die ("Username is already in use!");
}   

$query = $pdo -> prepare("SELECT * FROM Users WHERE Email =:Email");
$query->bindParam(':Email', $email);
$query ->execute();
$emailRes = $query->fetch(PDO::FETCH_ASSOC);

if ($emailRes['Email']==$_POST['email']) {
    die ("Email is already in use!");
}

我在我的应用程序的注册页面上有这个代码,当用户名可以免费使用但电子邮件不是,反之亦然我得到这个

注意:尝试访问 bool 类型值的数组偏移量

好的,结果返回 false,但在这种情况下该怎么办?注意:这是在 php v7.4 上,同样的事情也在 v7.3 上工作

【问题讨论】:

  • 只需检查是否返回了任何行,将if ($emailRes['Email']==$_POST['email']) { 替换为if ($emailRes) {$nameRes 也一样)
  • 好的,解决了,非常感谢。但是有人能解释一下为什么它过去可以在以前的版本上运行,而现在不能在这个新版本上运行吗?
  • 问题可能是您的查询没有返回任何行。如果返回一行,它会正常工作。
  • 这似乎是一个弱策略。如果有人在此用户名检查用户名是否存在时提交了用户名怎么办?
  • 当然,您可以通过 SELECT COUNT(Username) FROM Users WHERE Username =:Username OR Email =:Email 将其简化为一个查询

标签: php mysql pdo


【解决方案1】:

您收到此错误可能是因为在数据库中找不到符合您条件的记录。

解决此错误最简单的方法是先检查数据库是否返回任何内容。

$emailRes = $query->fetch(PDO::FETCH_ASSOC);
// VVV - Here I am checking if there was anything returned and then I check the condition
if($emailRes && $emailRes['Email']==$_POST['email']) {
    // ...
}

如果您不关心数据库是否返回任何内容,那么您可以简单地提供一个默认值。例如:

$emailRes = $query->fetch(PDO::FETCH_ASSOC);
$email = $emailRes['Email'] ?? ''; // default: empty string

使用 PDO 检查 DB 中是否存在的正确方法是:

$query = $pdo->prepare("SELECT COUNT(*) FROM Users WHERE Username =:Username");
$query->execute([':Username' => $name]);
if ($query->fetchColumn()) {
    throw new \Exception("Username is already in use!");
}

$query = $pdo->prepare("SELECT COUNT(*) FROM Users WHERE Email =:Email");
$query->execute([':Email' => $email]);
if ($query->fetchColumn()) {
    throw new \Exception("Email is already in use!");
}

我不是在 PHP 中获取行并再次进行比较,而是从数据库中获取匹配行的计数,并将该计数用作 if 语句中的布尔值。 fetchColumn() 将从第一行获取一列,如果我使用 COUNT(*),我知道总会有一行。

您也可以在一个查询中完成:

$query = $pdo->prepare("SELECT COUNT(*) FROM Users WHERE Username =:Username OR  Email =:Email");
$query->execute([':Username' => $name, ':Email' => $email]);
if ($query->fetchColumn()) {
    throw new \Exception("Username or email is already in use!");
}

【讨论】:

    猜你喜欢
    • 2020-08-01
    • 2021-03-31
    • 2020-11-01
    • 1970-01-01
    • 2020-04-27
    • 2020-12-16
    相关资源
    最近更新 更多