问:为什么password_verify持续失败?我检查了myql tbl列名(密码),没有错字。
$ query能够获取查询数据库的$ result($ result = true)。
password_verify的格式如下:
password_verify(用户输入密码,在数据库中找到的密码)。
[码]
如果(password_verify($ password,(string)$ row ['passwords']))
[/码]
我键入强制转换了password_verify的第二个参数,因为之前它给出了错误:
致命错误:未捕获的TypeError:password_verify()期望参数2为字符串,在/home/user/public_html/php/login.php:64中给出的null为堆栈跟踪:#0 /home/user/public_html/php/login.php (64):password_verify('password',NULL)#1 {main}在第64行的/home/luser/public_html/php/login.php中抛出
类型转换后,错误消失了。但是新问题。我得到回应,password_verify失败。我创建了一个条件,即回显,以在password_verify失败时回显:
[码]
如果(password_verify($ password,$ row ['passwords']))
{
$ _SESSION [“ user”] = $ username;
header(“ location:home.php?user = $ username”);
}
其他
{
echo“'password_verify'函数失败!”;
出口();
[/码]
}
在这里,完整的代码:
[码]
<?php
/ *
错误处理
* /
声明(strict_types = 1);
ini_set('display_errors','1');
ini_set('display_startup_errors','1');
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
包括'config.php';
//检查用户是否已经登录
如果(is_logged()=== true)
{
// 5秒钟后将用户重定向到首页。
header(“ refresh:5; url = home.php”);
出口; //
}
如果($ _SERVER ['REQUEST_METHOD'] ==“ POST”)
{
如果(isset($ _ POST [“ login_username”])&& isset($ _ POST [“ login_password”]))
{
$ username = trim($ _ POST [“ login_username”]); //
$ password = trim($ _ POST [“ login_password”]); //
$ hashed_password = password_hash($ _ POST [“ login_password”],PASSWORD_DEFAULT);
//选择用户名或电子邮件以检查Mysql DB是否已注册。
$ stmt = mysqli_stmt_init($ conn);
$ stmt = mysqli_prepare($ conn,“从用户名中选择用户名=?时选择ID,用户名,密码,电子邮件,accounts_activations_statuses。”);
mysqli_stmt_bind_param($ stmt,'s',$ email);
mysqli_stmt_execute($ stmt);
$ result = mysqli_stmt_bind_result($ stmt,$ db_id,$ db_username,$ db_password,$ db_email,$ db_account_activation_status); // ...这行。但不是两个。
$ row = mysqli_stmt_fetch($ stmt);
printf(“%s(%s)\ n”,$ row [“ usernames”],$ row [“ passwords]]);
echo“ var_dump(result)”; var_dump($ result)?> <br> <?php //在实验中,显示为:()bool(true);
如果($ result == false)
{
回显“错误的登录详细信息!”;
echo“ $ result == false”;
出口();
}
elseif($ row ['accounts_activations_statuses'] =='0')
{
{
回显“您尚未激活帐户!请查看您的电子邮件以获取说明。”
出口();
}
}
其他
{
回声'$ result == True'; //用于调试
echo“'从数据库中散列密码:'$ db_password <br>”; //用于调试
}
如果(password_verify($ password,$ row ['passwords']))
{
$ _SESSION [“ user”] = $ username;
header(“ location:home.php?user = $ username”);
}
其他
{
echo“'password_verify'函数失败!”;
出口();
}
}
}
?>
<!DOCTYPE html>
<html>
<头>
<title> <?php $ site_name?>登录页面</ title>
<meta charset =“ utf-8”>
</ head>
<身体>
<div class =“容器”>
<form method =“ post” action =“”>
<center> <h3> <?php $ site_name?>登录表单</ h3> </ center>
<div class =“ text-danger”>
<div class =“ form-group”>
<center> <label>用户名:</ label>
<input type =“ text” placeholder =“输入用户名” name =“ login_username” value =“” </ center>
</ div>
<div class =“ form-group”>
<center> <label>密码:</ label>
<input type =“ password”占位符=“输入密码” name =“ login_password” value =“”> </ center>
</ div>
<div class =“ form-group”>
<center> <输入类型=“提交” name =“ login_submit” value =“登录” class =“按钮成功按钮” /> </ center>
</ div>
</ form>
</ div>
</ body>
</ html>
[/码]
是什么导致password_verify无法通过验证?
答:看来问题出在“密码”列大小太小(50个字符)。将其切换为255应该会有所不同,但由于我未重新填充该列,因此昨晚在我的测试中没有这样做。另一个论坛上的其他人建议我重新填充,并且我刚刚阅读了他们的建议,并且在重新填充之后它仍然有效。刚刚在所有论坛上分享了这些知识,我就此问题打开了话题,因此也使其他新手受益。我知道这对专业人士来说并不是什么“可学的”。
http://www.webdeveloper.com/forum/showthread.php?366069-Why-password_verify-Not-Passing-The-Verification&p=1516863#post1516863
因此,当我键入正确的密码。
代码:
[代码]
<
错误处理
* /
clarify(strict_types = 1);
ini_set('display_errors','1');
ini_set('display_startup_errors','1');
error_reporting(E_ALL);
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
包括'config.php';
//检查用户是否已经登录,
如果(is_logged()=== true)
{
// 5秒钟后将用户重定向到主页。
header(“ refresh:2; url = home.php”);
出口; //
}
if($ _SERVER ['REQUEST_METHOD'] ==“ POST”)
{
if(isset($ _ POST [“ login_username_or_email”])&& isset($ _ POST [“ login_password”]))
{
$ username_or_email = trim($ _ POST [“ login_username_or_email”]); //
$ password = $ _POST [“ login_password”];
//选择用户名或电子邮件以检查Mysql DB是否已注册。
$ stmt = mysqli_stmt_init($ conn);
if(strpos(“ $ username_or_email”,“ @”)=== true)
{
$ email = $ username_or_email;
$ username =“”;
$ query =“从用户的电子邮件中选择ID,用户名,密码,电子邮件,accounts_activations_statuses =?
// i =整数;s =字符串; d =两倍;b =斑点。
$ stmt = mysqli_prepare($ conn,$ query);
mysqli_stmt_execute($ stmt);
// $ result = mysqli_stmt_get_result($ stmt); //使用此行(如果您需要获取数组的所有数据而不将其与变量关联,就像使用mysqli_stmt_bind_result一样),或者...
//从下面的行中注意,变量“ $ db_username”,“ $ db_account_activation_status ”与在$ query上选择的tbl列相关(“从用户.. WHERE中选择SELECT ID,用户名,accounts_activations_statuses。)
$ result = mysqli_stmt_bind_result($ stmt,$ db_id,$ db_username,$ db_password,$ db_email,$ db_account_activation_status) // ...这行,但不能同时使用。
}
else
{
$ username = $ username_or_email;
$ query =“在用户名=的情况下,从用户中选择ID,用户名,密码,电子邮件,accounts_activations_statuses。
// i =整数;s =字符串; d =两倍;b =斑点。
$ stmt = mysqli_prepare($ conn,$ query);
mysqli_stmt_bind_param($ stmt,'s',$ username);
mysqli_stmt_execute($ stmt);
// $ result = mysqli_stmt_get_result($ stmt); //使用这一行(如果您需要获取数组的所有数据而不将它们与变量关联,就像使用mysqli_stmt_bind_result一样),或者使用...
//从下面的行中注意到,变量“ $ db_email”,“ $ db_account_activation_status”与在$ query上选择的tbl列相关(“ SELECT ids,emails,accounts_activations_statuses From users .. WHERE)。
$ result = mysqli_stmt_bind_result($ stmt ,$ db_id,$ db_username,$ db_password,$ db_email,$ db_account_activation_status); // ...此行,但不能同时使用两者。#
}
// $ rownums = mysqli_num_rows($ result); //获取行匹配数
// // echo“ $ rownums”;
//要执行以下哪些操作以及为什么要这样做?
$ row = mysqli_stmt_fetch($ stmt);
// $ row = mysqli_fetch_array($ query,MYSQLI_ASSOC);
// $ row = mysqli_fetch_array($ result,MYSQLI_ASSOC);
mysqli_stmt_close($ stmt);
printf(“%s(%s)\ n”,$ row [“ usernames”],$ row [“ passwords]]);
if($ result == false)
{
在第73行echo“'$ result == false'!如果在第73行触发了!! <br>”;
出口();
}
elseif($ row ['accounts_activations_statuses'] =='0')
{
{
echo“您尚未激活帐户!请查看您的电子邮件以获取有关如何激活该帐户的说明。
如果找不到垃圾邮件文件夹,请检查该文件夹来自我们的电子邮件。”;
出口();
}
}
else
{
在第73行echo“'$ result == true'!其他在第86行触发!<br>”; //此ELSE在测试中被触发。这意味着$ result = TRUE;
}
if(password_verify($ password,$ db_password))
{
回显“如果为password_verify触发了IF!
//如果选中“记住我”复选框,则设置cookie。
// if(!empty($ _ POST [“ login_remember”]))// //使用此行....
if(isset($ _ POST ['login_remember'])&& $ _post ['login_remember'] ==“ “)// ...或此行。但不是两者!
{
setcookie(“ login_username”,$ username,time()+(10 * 365 * 24 * 60 * 60));
}
else
{
//如果Cookie可用,则使用它自动将用户登录到他/她的帐户!
if(isset($ _ COOKIE ['login_username']))
{
setcookie(“ login_username”,“”,“”);
}
}
$ _SESSION [“ user”] = $ username;
header(“ location:home.php?user = $ username”);
}
else
{
echo“其他在第111行被触发:不正确的用户凭证!
出口();
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<title> <?php $ site_name?>成员登录页面</ title>
<meta charset =“ utf-8”>
</ head>
<body>
<div class =“ container”>
<form method =“ post” action =“”>
<center> <h3> <?php $ site_name?>成员登录表单</ h3> </ center>
<div class =“ text -danger“>
<div class =” form-group“>
<center> <label>用户名/电子邮件:</ label>
<input type =” text“ placeholder =” Enter Username“ name =” login_username_or_email“ value =” <?php if(isset($ _ COOKIE [“ login_username_or_email”]))echo $ _COOKIE [“ login_username_or_email”];
?>“ </ center> </ div>
<div class =“ form-group”>
<center> <label>密码:</ label>
<input type =“ password”占位符=“输入密码” name =“ login_password” value =“ <?php if(isset( $ _COOKIE [“ login_password”]))echo $ _COOKIE [“ login_password”];?>“> </ center>
</ div>
<div class =” form-group“>
<center> <label>记住登录详细信息: </ label>
<input type =“ checkbox” name =“ login_remember” /> </ center>
</ div>
<div class =“ form-group”>
<center> <input type =“ submit” name =“ login_submit “ value =” Login“ class =” button button-success“ /></ center>
</ div>
<div class =“ form-group”>
<center> <font color =“ red” size =“ 3”> <b>忘记密码了?</ b> <br> <a href =“ login_password_reset.php”>在此处重置!</a> </ font> </ center>
<center> <font color =“ red” size =“ 3”> <b>未注册?</ b> <br> <a href="register.php">在此处注册!</a> </ font> </ center>
</ form>
</ div>
</ body>
</ html>
[/ code]
我对上述帖子中提到的代码进行了一些更改,因为在该论坛中被告知post):
1.检查$ result是否为true / false是没有意义的,因为如果我的代码没有错误,它将始终为true,否则可能始终为false。
2.同样,如果mysqli_stmt_fetch()找到结果行,则返回true,否则返回false。
我而是需要检查绑定到$ db_password的值以查看它是否正确。所以可能是这样的:
//好去了...
}
[/ code]
早在6天前,有人在那个论坛上建议我将我的代码缩减为:
[code]
if($ _SERVER ['REQUEST_METHOD'] ==“ POST”) //并不需要,因为您正在检查$ _POST
{
if(isset($ _ POST [“ login_username”])&& isset($ _ POST [“ login_password”])){
$ username = trim($ _ POST [“ login_username”] ); //
$ password = trim($ _ POST [“ login_password”]); //
$ hashed_password = password_hash($ _ POST [“ login_password”],PASSWORD_DEFAULT);
$ sql =“
选择
ID,
用户名,
密码,
电子邮件,
用户名在哪里=?
AND密码=?
“;
$ stmt = mysqli_prepare($ conn,$ sql);
mysqli_stmt_bind_param($ stmt,'ss,$ username,$ hashed_password);
mysqli_stmt_execute($ stmt);
if(mysqli_stmt_num_rows($ stmt)){
//找到匹配项,我们很乐意去...
} else {
//找不到用户名/密码时您可以做什么...
}
}
}
[/ code]