我一直在尝试编写一个PHP程序,让用户能够注册一个帐户并在注册后登录。我已经设法防止多个用户名的注册,并将所有注册的用户名和相应的密码存储在SQL表中,但我试图通过验证密码来登录工作,而PHP似乎无法识别SQL中的任何内容。我试过无数次mysqli_fetch_array
和mysqli_fetch_assoc
的变体,但都无济于事。完整的PHP代码张贴在下面,注释指定了最相关的部分。
<?php session_start(); ?>
<html>
<head>
<title>Test Form</title>
</head>
<body>
<link rel="stylesheet" type="text/css" href="main.css" />
<?php
include('mydbinfo.php');
$conn = new mysqli($dbhost, $dbuser, $dbpass, $dbname);
if ($conn->connect_error) {
echo("<font color='red'><p>Unable to connect to the database system</font>"."<font color='red'>Please try later.</font></p>");
exit();
}
if($_POST["email"].value == "" or $_POST["password"].value == "") {
print("<font color='red'><p>Sorry, you must enter values into each field.</font></p>");
} else {
$mail = $_POST["email"];
$_SESSION["sessUsername"] = $mail;
$pass = $_POST["password"];
$query = "SELECT user_password FROM logins WHERE email='$mail'";
$result=mysqli_query($conn,$query);
while($name = mysqli_fetch_array($result)) {
array_push($names,$name['email']);
for($n = 0; $n < count($names); $n++) {
if($names[$n] == $name['email']) {
$names++;
}
}
}
//Number of instances of SQL query result found in table.
$count = mysqli_num_rows($result);
if($count > 0) {
//Supposed to contain password which corresponds to a given user ID.
//This is the main issue.
$new=mysqli_fetch_array($result);
if($pass == $new) {
print "<font color='red'><p>Welcome back, $mail!</p></font>";
} else {
print "<font color='red'>Your reservation was invalid.</font>";
print($pass);
print($result);
}
} else {
echo "<font color='red'>Not found in table.</font>";
}
}
?>
</body>
</html>
<?php>
当您获取时,您将获取整行(或整个数据集)。
在您的示例中,您使用while
循环遍历所有行。之后,您再次获取另一行,但这不起作用,因为您已经使用循环获取了所有行。
此外,您将获得的数组(整行)与$pass
进行比较,这当然也不起作用。
那么,这个片段:
$new=mysqli_fetch_array($result);
if ($pass==$new)
{
print "<font color='red'><p>Welcome back, $mail!</p></font>";
}
应该是
if ($name['user_password'] == $pass)
{
print "<font color='red'><p>Welcome back, $mail!</p></font>";
}
$name
是您读取与电子邮件地址匹配的行的变量,因此按照我的建议更改代码使您的代码使用与之匹配的最后一个密码。
之后,还有其他问题需要解决。首先,在登录时,不需要while循环。希望只有一个匹配的帐户,您应该采取预防措施,确保您首先不会创建重复的帐户。
$name
也不是该变量的最佳名称,因为它包含一整行,其中包含名称和密码。
另外,我注意到查询根本不返回姓名或电子邮件,因此验证它们的循环可能也不起作用。所以也许再仔细看看是个好主意,或者甚至重新开始。毕竟,您已经进行了实验,尽管这提供了很多信息,但它也使代码变得一团糟。有时候,最好从头开始,把你学到的知识用于构建一个新的、改进的版本。
只是为了补充GolezTrol给出的答案,我认为你应该考虑阅读准备语句,这是一种简单的方法来防止SQL注入,这是你代码中的主要威胁。
您可以简单地检查组合email:password是否存在,只需执行以下查询:
SELECT email FROM logins WHERE email=? AND user_password=?
如果结果中有任何行,则登录凭据是正确的。使用这个查询,您将被设置为执行准备好的语句,请阅读
GolezTrol的答案和joaomlap的答案提供的附加信息很好地回答了这个问题。我只是想我应该提到一些其他的事情,这些事情现在可能不会引起挫折,但最终可能会。
First - <font>
和<p>
标签在以下代码行中顺序不正确:
echo("<font color='red'><p>Unable to connect to the database system</font>"
."<font color='red'>Please try later.</font></p>")
print("<font color='red'><p>Sorry, you must enter values into each field.
</font></p>");
你应该把开头的<font>
和<p>
标签切换成如下的样子:
echo("<p><font color='red'>Unable to connect to the database system</font>"
."<font color='red'>Please try later.</font></p>")
print("<p><font color='red'>Sorry, you must enter values into each field.
</font></p>");
更好的是,你应该给<p>
标签一个id
,就像<p id='red-text'>
一样,编辑你的main.css
样式表来改变red-text
id的文本颜色。这样就消除了所有<font>
标签的需要。
秒-所有<link>
标签应该位于开始和结束<head>
标签之间,如果<title>
标签存在,则位于<title>
标签下方。
所以你的代码:[& lt;每日;只出现在标题部分,但它可以出现任意次数。
-来自:HTML链接标签- W3Schools
<head>
<title>Test Form</title>
</head>
<body>
<link rel="stylesheet" type="text/css" href="main.css" />
<!-- more code -->
</body>
应该改成:
<head> <title>Test Form</title> <link rel="stylesheet" type="text/css" href="main.css" /> </head>
<body>
<link rel="stylesheet" type="text/css" href="main.css" />
<!-- more code -->
</body>
第三-代码末尾悬挂的<?php
标记是怎么回事?只有在纯php
代码的文件中使用时,才能获得不关闭<?php
标记的好处。
如果文件是纯PHP代码,最好省略文件末尾的PHP结束标记。这可以防止在PHP结束标记之后意外添加空白或新行,这可能会导致不必要的效果,因为当程序员无意在脚本中此时发送任何输出时,PHP将开始输出缓冲。 - PHP手册