Php Can';无法获取用户输入的密码\u verify()

Php Can';无法获取用户输入的密码\u verify(),php,mysql,pdo,Php,Mysql,Pdo,这是登录代码,我试图让密码验证工作,但它不想。问题似乎出在count($sql->fetchAll())>0上,或者我调用了错误的变量到密码\u verify() 这是注册码 function register($uname,$umail,$upass) { $DB_con = null; try { $DB_con = new PDO("mysql:host=$host;dbname=$dbname", "$username" ,"$password");

这是登录代码,我试图让密码验证工作,但它不想。问题似乎出在
count($sql->fetchAll())>0
上,或者我调用了错误的变量到
密码\u verify()

这是注册码

function register($uname,$umail,$upass)
    {

        $DB_con = null;

try
{
     $DB_con = new PDO("mysql:host=$host;dbname=$dbname", "$username" ,"$password");
     $DB_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
     echo $e->getMessage();
}   



       try
       {
           $new_password = password_hash($upass, PASSWORD_DEFAULT);

           $stmt = $DB_con->prepare("INSERT INTO users(user_name,user_email,user_pass) 
                                                       VALUES(:uname, :umail, :upass)");

           $stmt->bindparam(":uname", $uname);
           $stmt->bindparam(":umail", $umail);
           $stmt->bindparam(":upass", $new_password);            
           $stmt->execute(); 
           return $stmt; 

       }
       catch(PDOException $e)
       {
           echo $e->getMessage();
       }    

    }

有几件事需要用这段代码来清理

让我们从您的
register()
函数开始。这里有一个明显的语法错误(您建立连接的地方),
“$password”
。然后该函数不知道
$dbname
$username
$password
是什么(对于连接),这些变量不在函数的范围内(它可以看到)。通常,最好将连接对象作为参数传递,而不是每次调用
register()
函数时都创建一个新对象。对此进行了修改,并进行了一些清理,结果如下所示

function register($DB_con, $uname ,$umail, $upass) {
    try {
        $new_password = password_hash($upass, PASSWORD_DEFAULT);

        $stmt = $DB_con->prepare("INSERT INTO users (user_name, user_email, user_pass) 
                                                   VALUES (:uname, :umail, :upass)");

        $stmt->bindparam(":uname", $uname);
        $stmt->bindparam(":umail", $umail);
        $stmt->bindparam(":upass", $new_password);            
        return $stmt->execute(); 

    } catch(PDOException $e) {
        echo $e->getMessage();
    }
}
$signup = isset($_POST['signup']) ? $_POST['signup'] : false;
$submit = isset($_POST['submit']) ? $_POST['submit'] : false;
$username = isset($_POST['username']) ? $_POST['username'] : false;
$password = isset($_POST['password']) ? $_POST['password'] : false;

if ($submit && $username && $password) {
    $sql = $DB_con->prepare("SELECT * FROM users WHERE user_name=:user_name");
    $sql->bindParam(':user_name', $username, PDO::PARAM_STR);
    $sql->execute();

    if ($check_user=$sql->fetch(PDO::FETCH_ASSOC)) {
        if (password_verify($password, $check_user['user_pass'])) {
            $_SESSION['logged_in'] = true;  
            // Unset errors
            unset($_SESSION['error']);
        } else {
            // Invalid password
        }
    } else {
        // No user with that username
    }
} else {
    //displays error
    $_SESSION['error'] = 'Please enter all fields';
}

if ($signup) {
    header('Location: signup.php');
}
exit;
并被当作

register($DB_con, 'Nader', 'example@example.com', 'pa$$w0rd'); // True or false
然后在你的登录上。这有点混乱,你做了一些错事。到目前为止我发现

  • 执行后获取
  • 选择
    ,其中
    未删除的密码等于散列密码(不会返回任何行)
  • count($sql->fetchAll())>0
    将为零,因为您已经获取了一次,并且将只有一个用户=>这意味着一行。获取一行意味着没有更多的内容可获取,因此
    fetchAll()
    为空
  • 除了($check\u user=$sql->fetch())检查是否有行之外,您不需要做更多的检查

更正并解释了以上几点,您的代码看起来像这样

function register($DB_con, $uname ,$umail, $upass) {
    try {
        $new_password = password_hash($upass, PASSWORD_DEFAULT);

        $stmt = $DB_con->prepare("INSERT INTO users (user_name, user_email, user_pass) 
                                                   VALUES (:uname, :umail, :upass)");

        $stmt->bindparam(":uname", $uname);
        $stmt->bindparam(":umail", $umail);
        $stmt->bindparam(":upass", $new_password);            
        return $stmt->execute(); 

    } catch(PDOException $e) {
        echo $e->getMessage();
    }
}
$signup = isset($_POST['signup']) ? $_POST['signup'] : false;
$submit = isset($_POST['submit']) ? $_POST['submit'] : false;
$username = isset($_POST['username']) ? $_POST['username'] : false;
$password = isset($_POST['password']) ? $_POST['password'] : false;

if ($submit && $username && $password) {
    $sql = $DB_con->prepare("SELECT * FROM users WHERE user_name=:user_name");
    $sql->bindParam(':user_name', $username, PDO::PARAM_STR);
    $sql->execute();

    if ($check_user=$sql->fetch(PDO::FETCH_ASSOC)) {
        if (password_verify($password, $check_user['user_pass'])) {
            $_SESSION['logged_in'] = true;  
            // Unset errors
            unset($_SESSION['error']);
        } else {
            // Invalid password
        }
    } else {
        // No user with that username
    }
} else {
    //displays error
    $_SESSION['error'] = 'Please enter all fields';
}

if ($signup) {
    header('Location: signup.php');
}
exit;
这假定数据库中的用户名是唯一的

可能还有更多我看不到的问题,这就是为什么您应该通过添加

<?php
error_reoprting(E_ALL);
ini_set("display_errors", 1);

这段代码有几件事情需要清理

让我们从您的
register()
函数开始。这里有一个明显的语法错误(在您建立连接的地方),
“$password”
。然后,该函数不知道
$dbname
$username
$password
是什么(对于连接),这些变量不在函数的范围内(它可以看到)。通常,最好将连接对象作为参数传递,而不是每次调用
register()
函数时都创建一个新对象。对此进行了修改,并进行了一点清洁,看起来像这样

function register($DB_con, $uname ,$umail, $upass) {
    try {
        $new_password = password_hash($upass, PASSWORD_DEFAULT);

        $stmt = $DB_con->prepare("INSERT INTO users (user_name, user_email, user_pass) 
                                                   VALUES (:uname, :umail, :upass)");

        $stmt->bindparam(":uname", $uname);
        $stmt->bindparam(":umail", $umail);
        $stmt->bindparam(":upass", $new_password);            
        return $stmt->execute(); 

    } catch(PDOException $e) {
        echo $e->getMessage();
    }
}
$signup = isset($_POST['signup']) ? $_POST['signup'] : false;
$submit = isset($_POST['submit']) ? $_POST['submit'] : false;
$username = isset($_POST['username']) ? $_POST['username'] : false;
$password = isset($_POST['password']) ? $_POST['password'] : false;

if ($submit && $username && $password) {
    $sql = $DB_con->prepare("SELECT * FROM users WHERE user_name=:user_name");
    $sql->bindParam(':user_name', $username, PDO::PARAM_STR);
    $sql->execute();

    if ($check_user=$sql->fetch(PDO::FETCH_ASSOC)) {
        if (password_verify($password, $check_user['user_pass'])) {
            $_SESSION['logged_in'] = true;  
            // Unset errors
            unset($_SESSION['error']);
        } else {
            // Invalid password
        }
    } else {
        // No user with that username
    }
} else {
    //displays error
    $_SESSION['error'] = 'Please enter all fields';
}

if ($signup) {
    header('Location: signup.php');
}
exit;
并被当作

register($DB_con, 'Nader', 'example@example.com', 'pa$$w0rd'); // True or false
然后进入您的登录。这有点乱,你做了一些错事。到目前为止我发现的是

  • 执行后获取
  • 选择
    ,其中
    未删除的密码等于散列密码(不会返回任何行)
  • count($sql->fetchAll())>0
    将为零,因为您已经获取了一次,并且只有一个用户=>这意味着一行。获取一意味着没有更多的内容可获取,因此
    fetchAll()
    为空
  • 除了($check\u user=$sql->fetch())
检查是否有行之外,您不需要做更多的检查

更正并解释了以上几点,您的代码看起来像这样

function register($DB_con, $uname ,$umail, $upass) {
    try {
        $new_password = password_hash($upass, PASSWORD_DEFAULT);

        $stmt = $DB_con->prepare("INSERT INTO users (user_name, user_email, user_pass) 
                                                   VALUES (:uname, :umail, :upass)");

        $stmt->bindparam(":uname", $uname);
        $stmt->bindparam(":umail", $umail);
        $stmt->bindparam(":upass", $new_password);            
        return $stmt->execute(); 

    } catch(PDOException $e) {
        echo $e->getMessage();
    }
}
$signup = isset($_POST['signup']) ? $_POST['signup'] : false;
$submit = isset($_POST['submit']) ? $_POST['submit'] : false;
$username = isset($_POST['username']) ? $_POST['username'] : false;
$password = isset($_POST['password']) ? $_POST['password'] : false;

if ($submit && $username && $password) {
    $sql = $DB_con->prepare("SELECT * FROM users WHERE user_name=:user_name");
    $sql->bindParam(':user_name', $username, PDO::PARAM_STR);
    $sql->execute();

    if ($check_user=$sql->fetch(PDO::FETCH_ASSOC)) {
        if (password_verify($password, $check_user['user_pass'])) {
            $_SESSION['logged_in'] = true;  
            // Unset errors
            unset($_SESSION['error']);
        } else {
            // Invalid password
        }
    } else {
        // No user with that username
    }
} else {
    //displays error
    $_SESSION['error'] = 'Please enter all fields';
}

if ($signup) {
    header('Location: signup.php');
}
exit;
这假定数据库中的用户名是唯一的

可能还有更多我看不到的问题,这就是为什么您应该通过添加

<?php
error_reoprting(E_ALL);
ini_set("display_errors", 1);

我可以看到两件事:验证中的check\u user
中缺少
$
,并且在执行之前获取。寄存器函数中的语法错误,请参见highlightingOh,另一件事:您试图选择密码与未删除密码匹配的位置,使用
password\u hash()
时无法这样做。从您的位置删除密码clause@Qirel,你好,朋友,非常感谢你的回复,注册函数中的语法错误只是我匆忙更改登录信息来发布它。当你说在执行之前抓取时,你的意思是我需要把$check\u user=$sql->fetch(PDO::fetch\u ASSOC);在$success之后?是的,基本上。还有其他问题,我已经发布了一个关于我发现的问题的答案。我可以看到两件事:验证中的check\u user中缺少
$
,并且您在执行之前正在获取。以及register函数中的语法错误,请参阅highlightingOh,另一件事:您正在尝试选择密码与未删除密码匹配的位置,使用
密码\u hash()时不能执行此操作。从您的位置删除密码clause@Qirel,你好,朋友,非常感谢你的回复,注册函数中的语法错误只是我匆忙更改登录信息来发布它。当你说在执行之前抓取时,你的意思是我需要把$check\u user=$sql->fetch(PDO::fetch\u ASSOC);在$success之后?是的,基本上。还有其他问题,我已经发布了一个关于我发现的问题的答案。嗨,非常感谢你的帮助,它现在正在工作。我对PHP真的很陌生,所以我尝试了很多不同的东西,因此代码很混乱,非常感谢您花时间修改它。关于DB连接,我将实际值更改为$dbname等,因为它有我的uni凭据作为值。事后看来,我应该用一种不同的方式来表达这些价值观,我下次会记住这一点。很乐意帮忙!我们都从某个地方开始;-)使用参数化查询和适当的密码散列,从PDO开始,您做得很好,所以继续吧!竖起大拇指如果这个答案为你提供了一个很好的解决方案,请务必向上投票!干杯!:-)嗨,非常感谢你的帮助,现在开始工作了。我对PHP真的很陌生,所以我尝试了很多不同的东西,因此代码很混乱,非常感谢您花时间修改它。关于DB连接,我将实际值更改为$dbname等,因为它有我的uni凭据作为值。嗨