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

2021-12-26 00:00:00 php mysql pdo
$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!");
}

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

I have this code on the registration page of my app and when Username is free to use but email is not and vice versa I get this

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

Notice: Trying to access array offset on value of type bool

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

Ok the result is returning false but what to do in this situation? Note: This is on php v7.4 this same thing was working on v7.3

推荐答案

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

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

The easiest way to solve this error is to check if the database returned anything first.

$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']) {
    // ...
}

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

If you don't care whether the database returned anything, then you can simply provide a default value. For example:

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

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

The correct way to check for existance in DB using PDO is:

$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(*) 我知道总会有一行.

Instead of fetching the row and doing the comparison again in PHP I am fetching a count of matching rows from the database and I use that count as a boolean in the if statement. fetchColumn() will fetch a single column from the first row and if I use COUNT(*) I know there will always be one row.

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

You can also do it in one query:

$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!");
}

相关文章