创建PHP登录和注册表格的方法

338 阅读4分钟

当我们想储存网站用户的信息时,用户登录和注册系统是超级有用的。这适用于从教育网站(可能存储课程进度和分数)到电子商务网站(将存储客户过去购买的信息)的所有内容。

在本教程中,我将教你如何从头开始创建你自己的PHP登录和注册表格。

创建登录和注册表格

我们的第一步将是创建一个登录表单和一个注册表单。这些表单实际上是非常简单的。注册表格将只要求提供一个用户名、电子邮件和密码。用户名和电子邮件对每个注册者来说都是唯一的。如果有人试图用同一个电子邮件地址创建两个账户,我们会向他们显示一个错误信息,让他们知道这个电子邮件已经被使用了。

注册表的编码

这里是创建注册表的HTML。你必须把它放在一个名为register.php的文件中。

<form method="post" action="" name="signup-form">
<div class="form-element">
<label>Username</label>
<input type="text" name="username" pattern="[a-zA-Z0-9]+" required />
</div>
<div class="form-element">
<label>Email</label>
<input type="email" name="email" required />
</div>
<div class="form-element">
<label>Password</label>
<input type="password" name="password" required />
</div>
<button type="submit" name="register" value="register">Register</button>
</form>

这个表单是非常基本的,但我们确实使用了HTML5来做一些非常基本的输入验证。例如,当用户输入的电子邮件地址的格式不正确时,使用type="email" ,会提醒用户。同样地,在用户名上使用pattern 属性将确保用户名只由字母数字字符组成。

登录表单的编码

这里是登录表单的HTML。你可以把它放在一个名为login.php的文件中。

<form method="post" action="" name="signin-form">
  <div class="form-element">
    <label>Username</label>
    <input type="text" name="username" pattern="[a-zA-Z0-9]+" required />
  </div>
  <div class="form-element">
    <label>Password</label>
    <input type="password" name="password" required />
  </div>
  <button type="submit" name="login" value="login">Log In</button>
</form>

用CSS为表单设计样式

这里有一些CSS,你可以应用到这些表单上。

* {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}
body {
    margin: 50px auto;
    text-align: center;
    width: 800px;
}
h1 {
    font-family: 'Passion One';
    font-size: 2rem;
    text-transform: uppercase;
}
label {
    width: 150px;
    display: inline-block;
    text-align: left;
    font-size: 1.5rem;
    font-family: 'Lato';
}
input {
    border: 2px solid #ccc;
    font-size: 1.5rem;
    font-weight: 100;
    font-family: 'Lato';
    padding: 10px;
}
form {
    margin: 25px auto;
    padding: 20px;
    border: 5px solid #ccc;
    width: 500px;
    background: #eee;
}
div.form-element {
    margin: 20px 0;
}
button {
    padding: 10px;
    font-size: 1.5rem;
    font-family: 'Lato';
    font-weight: 100;
    background: yellowgreen;
    color: white;
    border: none;
}
p.success,
p.error {
    color: white;
    font-family: lato;
    background: yellowgreen;
    display: inline-block;
    padding: 2px 10px;
}
p.error {
    background: orangered;
}

这包含了一些额外的错误信息和标题的样式设计规则。当你创建自己的表单时,本节中的HTML和CSS可以作为你项目的基础,这可能需要不同的样式和输入字段。

创建用户表并连接到数据库

下一步是创建一个用户表,它将存储所有关于注册用户的信息。在我们的例子中,这个表只是由四列组成:

  1. 一个自动递增的ID
  2. 一个唯一的用户名
  3. 一个电子邮件
  4. 一个密码

你可以使用下面的SQL语句来快速创建该表。

CREATE TABLE `users` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
    `username` varchar(25) NOT NULL,
    `password` varchar(255) NOT NULL,
    `email` varchar(100) NOT NULL,
    PRIMARY KEY (`id`),
    UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1;

现在,创建一个名为config.php的文件,并在其中写下以下代码以连接到数据库。

<?php
    define('USER', 'root');
    define('PASSWORD', '');
    define('HOST', 'localhost');
    define('DATABASE', 'test');
    try {
        $connection = new PDO("mysql:host=".HOST.";dbname=".DATABASE, USER, PASSWORD);
    } catch (PDOException $e) {
        exit("Error: " . $e->getMessage());
    }
?>

把数据库名称改为你的数据库的名称。这个文件将被用来建立与数据库的连接。

对用户注册进行编码

现在终于到了实现注册功能的时候了。这段代码的主要功能是检查提供的电子邮件是否已经注册。如果不是,我们就把用户名、电子邮件和密码输入数据库。

将以下代码放在registration.php的顶部。

<?php
    session_start();
    include('config.php');
    if (isset($_POST['register'])) {
        $username = $_POST['username'];
        $email = $_POST['email'];
        $password = $_POST['password'];
        $password_hash = password_hash($password, PASSWORD_BCRYPT);
        $query = $connection->prepare("SELECT * FROM users WHERE email=:email");
        $query->bindParam("email", $email, PDO::PARAM_STR);
        $query->execute();
        if ($query->rowCount() > 0) {
            echo '<p class="error">The email address is already registered!</p>';
        }
        if ($query->rowCount() == 0) {
            $query = $connection->prepare("INSERT INTO users(username,password,email) VALUES (:username,:password_hash,:email)");
            $query->bindParam("username", $username, PDO::PARAM_STR);
            $query->bindParam("password_hash", $password_hash, PDO::PARAM_STR);
            $query->bindParam("email", $email, PDO::PARAM_STR);
            $result = $query->execute();
            if ($result) {
                echo '<p class="success">Your registration was successful!</p>';
            } else {
                echo '<p class="error">Something went wrong!</p>';
            }
        }
    }
?>

第一步是包括config.php并启动会话。这可以帮助我们存储任何我们想在各个页面保留的信息。

接下来,我们通过检查$_POST['register'] ,检查用户是否点击了注册按钮来提交表单。请永远记住,将密码作为纯文本存储并不是一个好主意。出于这个原因,我们使用password_hash()函数,然后将该哈希值存储在我们的数据库中。这个特殊的函数使用随机生成的盐创建了一个60个字符的哈希值。

最后,我们执行查询,并检查一个给定的电子邮件地址是否存在非零行号。如果有,用户会收到一条信息,说这个电子邮件地址已经被注册了。

如果不存在给定电子邮件地址的行,我们就把提供的信息输入数据库,并让用户知道注册成功了。

实现登录功能

在上一步中,我们写了登录用户的代码。这一次,我们简单地检查数据库中的信息,看看输入到表单中的用户名和密码组合是否正确。

下面是login.php顶部的代码。

<?php
    session_start();
    include('config.php');
    if (isset($_POST['login'])) {
        $username = $_POST['username'];
        $password = $_POST['password'];
        $query = $connection->prepare("SELECT * FROM users WHERE username=:username");
        $query->bindParam("username", $username, PDO::PARAM_STR);
        $query->execute();
        $result = $query->fetch(PDO::FETCH_ASSOC);
        if (!$result) {
            echo '<p class="error">Username password combination is wrong!</p>';
        } else {
            if (password_verify($password, $result['password'])) {
                $_SESSION['user_id'] = $result['id'];
                echo '<p class="success">Congratulations, you are logged in!</p>';
            } else {
                echo '<p class="error">Username password combination is wrong!</p>';
            }
        }
    }
?>

这里需要注意的一件事是,我们并没有在一个步骤中比较用户名和密码。因为密码实际上是以散列形式存储的,我们首先需要在提供的用户名的帮助下获取散列值。一旦我们得到哈希值,我们就可以使用 password_verify()函数来比较密码和哈希值。

一旦我们成功确认了密码,我们将$_SESSION['user_id'] 变量设置为数据库中该用户的ID。你也可以在这里设置其他变量的值。

限制对页面的访问

大多数要求用户注册的网站都有一些其他页面,用户在这些页面上访问和存储私人数据。你可以使用会话变量来保护这些页面。如果会话变量没有设置,只需将用户重定向到登录页面。否则,向他们展示页面的内容。

<?php
    session_start();
    if(!isset($_SESSION['user_id'])){
        header('Location: login.php');
        exit;
    } else {
        // Show users the page!
    }
?>

你唯一要做的是确保脚本在开始时包含session_start()

解决常见的错误

在使用这个脚本时,你可能会遇到三种类型的错误。

1.由于变量名不正确而产生的错误

最常见的错误来源之一是某个变量的大写字母不正确。因此,对所有的变量坚持使用相同的命名规则是很重要的。举个例子,$_POST 超级全局中的键是基于分配给表单中输入元素的名称值。这意味着,$_POST['USERNAME']$_POST['username'] 将有不同的值。

2.2. "标题已发送"错误

一些函数如session_start()header() 修改了 HTTP 头信息。由于PHP在输出东西之前会刷新所有的头信息,所以在输出东西之前调用所有这些函数是很重要的。这包括任何原始的HTML或在开头的<?php 标签前无意的空格。

3.会话变量不能跨页保存

只有当你在一个页面上调用了函数session_start() ,你才能在该页面上访问会话变量。如果你不能在一个页面上访问$_SESSION 超全局中的值,这可能是因为你忘记了调用session_start() 。还要记得在你在页面上输出任何东西之前调用该函数。否则,你会遇到 "Headers already sent" 的错误。