知识

php登陆页面完整代码

字号+ 作者:烟消火灭网 来源:时尚 2026-10-17 09:01:22 我要评论(0)

登录页面不是只有表单和按钮。真正写起来,最容易被忽略的是错误处理——比如用户提交空密码,或者数据库查不到这个人。下面这份代码我用了好几年,改过几轮,现在算是比较稳的版本。 先看目录结构:login.p

登录页面不是陆页只有表单和按钮。真正写起来,面完码最容易被忽略的整代是错误处理——比如用户提交空密码,或者数据库查不到这个人。陆页下面这份代码我用了好几年,面完码改过几轮,整代现在算是陆页比较稳的版本。

先看目录结构:login.php 负责显示和验证,面完码config.php 放数据库连接,整代style.css 管外观。陆页这样拆开,面完码以后换数据库或改样式不用动逻辑。整代

config.php 很简单,陆页但别把密码硬编码在里面。面完码我习惯用环境变量,整代没有的话给个默认值:

<?php $host = getenv('DB_HOST') ?: 'localhost'; $db = getenv('DB_NAME') ?: 'test_db'; $user = getenv('DB_USER') ?: 'root'; $pass = getenv('DB_PASS') ?: ''; $charset = 'utf8mb4'; $dsn = "mysql:host=$host;dbname=$db;charset=$charset"; $options = [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]; try {  $pdo = new PDO($dsn, $user, $pass, $options); } catch (PDOException $e) {  die('数据库连接失败:' . $e->getMessage()); } ?> 

注意 PDO::ATTR_EMULATE_PREPARES 设为 false,这样预处理语句才是真的预处理,不是拼字符串。很多注入漏洞就出在这。

login.php 分两段:先处理 POST,再渲染 HTML。处理逻辑放最上面,避免“headers already sent”错误。

<?php session_start(); require 'config.php'; $error = ''; if ($_SERVER['REQUEST_METHOD'] === 'POST') {  $username = trim($_POST['username'] ?? ''); $password = $_POST['password'] ?? ''; if ($username === '' || $password === '') {  $error = '用户名和密码都不能为空'; } else {  $stmt = $pdo->prepare('SELECT id, password_hash FROM users WHERE username = ? LIMIT 1'); $stmt->execute([$username]); $user = $stmt->fetch(); if ($user && password_verify($password, $user['password_hash'])) {  session_regenerate_id(true); $_SESSION['user_id'] = $user['id']; header('Location: dashboard.php'); exit; } else {  $error = '用户名或密码错误'; } } } ?> 

几个细节:trim() 去掉用户名两边的空格,但密码不能 trim,因为空格可能是密码的一部分。session_regenerate_id(true) 防止会话固定攻击。登录成功后跳转,不要直接输出内容,否则刷新会重复提交。

下面是 HTML 部分,和 PHP 混在一起,但保持干净:

<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>登录</title> <link rel="stylesheet" href="style.css"> </head> <body> <div class="login-box"> <h1>登录</h1> <?php if ($error): ?> <p class="error"><?= htmlspecialchars($error) ?></p> <?php endif; ?> <form method="post" action=""> <label for="username">用户名</label> <input type="text" id="username" name="username" required autofocus> <label for="password">密码</label> <input type="password" id="password" name="password" required> <button type="submit">登录</button> </form> </div> </body> </html> 

htmlspecialchars($error) 不能省,万一错误信息里带了用户输入,会变成 XSS 漏洞。表单的 action 留空,提交到当前页面,这样不用维护两个文件。

style.css 就简单写几行,够用就行:

body {  font-family: system-ui, sans-serif; background: #f2f2f2; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; } .login-box {  background: #fff; padding: 2rem; border-radius: 8px; box-shadow: 0 4px 12px rgba(0,0,0,0.1); width: 320px; } .login-box h1 {  margin: 0 0 1.5rem; font-size: 1.5rem; } .login-box label {  display: block; margin-bottom: 0.25rem; font-size: 0.9rem; } .login-box input {  width: 100%; padding: 0.5rem; margin-bottom: 1rem; border: 1px solid #ccc; border-radius: 4px; box-sizing: border-box; } .login-box button {  width: 100%; padding: 0.6rem; background: #0066cc; color: #fff; border: none; border-radius: 4px; cursor: pointer; } .login-box button:hover {  background: #0055aa; } .error {  color: #cc0000; font-size: 0.9rem; margin-bottom: 1rem; } 

数据库表结构别忘了建:

CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL ); 

插入测试用户时,用 password_hash('你的密码', PASSWORD_DEFAULT) 生成哈希,别存明文。我见过有人直接存 md5,那跟没加密差不多。

最后提一句:这个登录页面没有验证码、没有登录失败次数限制,生产环境得加上。但作为基础骨架,它已经避开了最常见的几个坑——SQL 注入、XSS、会话固定。剩下的按需扩展就行。

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • 网站源码百度网盘

    网站源码百度网盘

    2026-10-17 07:53

  • flag值

    flag值

    2026-10-17 06:19

  • 渗透测试过程中各类报文含义

    渗透测试过程中各类报文含义

    2026-10-17 06:18

  • 此解决方案包含具有漏洞的包

    此解决方案包含具有漏洞的包

    2026-10-17 06:17

网友点评