目录
用户数据文件 (users.php)
HTML 登录表单 (login.html)
PHP 登录处理脚本 (login_process.php)
欢迎页面 (welcome.php)
注销脚本 (logout.php)
效果展示
用户名和密码错误时
用户名和密码正确时
用户数据文件 (users.php
)
用于保存用户信息,用户名和他对应的密码。
<?php
// users.php
return [
'users' => [
['username' => 'Yanqing', 'password' => '无敌剑士123'],
['username' => 'JingYuan', 'password' => '实名上网'],
['username' => 'Guinaifen', 'password' => '小桂子Guinevere']
]
];
?>
return
:返回一个数组。
数组中的键 'users'
对应一个包含多个用户信息的数组。
每个用户信息也是一个数组,包含 username
和 password
键。
这里相当于一个二维数组:
username | Yanqing | JingYuan | Guinaifen |
password | 无敌剑士123 | 实名上网 | 小桂子Guinevere |
HTML 登录表单 (login.html
)
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>登录系统</title>
</head>
<body>
<h2>登录</h2>
<form action="login_process.php" method="post">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" required>
<label for="password">密码:</label>
<input type="password" id="password" name="password" required>
<input type="submit" value="登录">
</form>
</body>
</html>
lang="zh-CN"
告诉浏览器和搜索引擎此页面主要使用的语言是简体中文。
<meta charset="UTF-8">
这段代码指定了文档的字符编码为UTF-8。
<form>
:定义了一个表单,用户可以在此输入数据。
<label>
:这是一个标签元素,用于为表单中的输入字段提供描述性的标签。
for="username"
:这是一个属性,用来关联标签与具体的表单控件。属性值(这里是"username")应该与控件的id
属性相匹配。
action="login_process.php"
:表单提交时的数据将发送到 login_process.php
文件。
method="post"
:数据将以POST方式发送。
<input>
:定义了两个输入字段,一个是用户名,一个是密码。
required
:这两个字段必须填写。
<input type="submit">
:定义了一个提交按钮,用户点击后将提交表单到login_process.php
文件。
PHP 登录处理脚本 (login_process.php
)
<?php
require_once 'users.php';
// 初始化变量和错误信息
$usernameErr = $passwordErr = "";
$username = $password = "";
// 检查是否为POST请求
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// 获取表单数据
$username = test_input($_POST["username"]);
$password = test_input($_POST["password"]);
// 加载用户数据
$users = include 'users.php';
// 初始化登录标志
$loginSuccess = false;
// 遍历用户数据,查找匹配的用户名和密码
foreach ($users['users'] as $user) {
if ($user['username'] === $username && $user['password'] === $password) {
$loginSuccess = true;
break;
}
}
// 检查登录是否成功
if ($loginSuccess) {
// 登录成功,重定向到欢迎页面
session_start();
$_SESSION['loggedin'] = true;
$_SESSION['username'] = $username;
header("location: welcome.php");
exit;
} else {
// 登录失败,显示错误信息
$usernameErr = "用户名或密码错误";
}
}
// 清理数据
function test_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>登录失败</title>
</head>
<body>
<h2>登录失败</h2>
<p><?php echo $usernameErr; ?></p>
<a href="login.html">返回登录页面</a>
</body>
</html>
require_once 'users.php';
:引入用户数据文件。
if ($_SERVER["REQUEST_METHOD"] == "POST") { ... }
:检查是否为POST请求。
test_input()
:用于清理输入数据,防止XSS攻击。
遍历用户数据,检查输入的用户名和密码是否匹配。
如果登录成功,session_start()
函数开始一个新的会话或者重新启动一个已存在的会话。设置一个名为loggedin
的会话变量,并将其值设置为true
,表明用户已经成功登录。设置了另一个会话变量username
,其值为用户登录时提供的用户名$username
。header()
函数用于发送原始HTTP头,这里发送一个重定向到welcome.php
页面的响应头。
如果登录失败,显示错误信息,并提供链接返回登录页面。
欢迎页面 (welcome.php
)
<?php
session_start();
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) {
header("location: login.html");
exit;
}
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>欢迎</title>
</head>
<body>
<h2>欢迎,<?php echo htmlspecialchars($_SESSION['username']); ?>!</h2>
<p>您已经成功登录。</p>
<a href="logout.php">注销</a>
</body>
</html>
session_start();
:启动会话。
if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true)
检查是否存在$_SESSION['loggedin']
并且它的值是否为true
。如果没有设置或不是true
,则认为用户未登录。
header("location: login.html");
如果用户未登录,则发送一个HTTP头部信息,重定向用户到登录页面login.html
。
检查是否已登录,如果没有,则重定向到登录页面。
<?php echo htmlspecialchars($_SESSION['username']); ?>
输出会话中存储的用户名,同时使用htmlspecialchars
函数防止XSS攻击。
显示用户名,并提供注销链接。
注销脚本 (logout.php
)
<?php
session_start();
// 销毁会话
$_SESSION = array();
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
session_destroy();
header("location: login.html");
exit;
?>
session_start();
这行代码开始一个新的会话或者恢复一个已经存在的会话。
$_SESSION = array();
这一行代码将$_SESSION
超全局数组清空,即将其中的所有会话变量设置为空数组。这是注销过程的第一步,确保会话中的所有数据都被清除。
if (ini_get("session.use_cookies")) {
$params = session_get_cookie_params();
setcookie(session_name(), '', time() - 42000,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]
);
}
这部分代码用于删除与会话相关的Cookie。如果配置了使用Cookies来维持会话(session.use_cookies
为true
),则执行以下操作:
使用session_get_cookie_params()
获取当前会话Cookie的参数。
使用setcookie()
函数创建一个过期的Cookie,其名称与会话名称相同,有效期设置为过去的某个时间点(time() - 42000
),这实际上是在删除该Cookie。
session_name()
返回会话的名称。
$params["path"]
, $params["domain"]
, $params["secure"]
, $params["httponly"]
分别设置Cookie的有效路径、域名、是否只在安全连接下发送以及是否只通过HTTP协议发送。
session_destroy();
这行代码彻底销毁会话数据。session_destroy()
函数会删除服务器端与会话相关的文件或数据库记录,但不会删除客户端的Cookie(这就是为什么前面需要使用setcookie()
来删除Cookie)。
header("location: login.html");
exit;
?>
这部分代码用于重定向用户到登录页面,并结束脚本的执行:
header("location: login.html")
发送一个HTTP头来重定向用户到login.html
页面。exit;
确保在发送了重定向头之后立即停止脚本的执行,防止后续代码干扰重定向操作。
效果展示
用户名和密码错误时
用户名和密码正确时