You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用$_SESSION为不同输入字段显示多条错误信息?

注册页面字段错误信息显示问题解决

我正在做一个带多输入字段的注册页面,现在卡在了无法为每个字段单独显示错误信息这一步。注册逻辑单独放在register_func.php里,试了好几种办法都没用。下面是我当前的代码:

原代码

register_func.php

<?php
session_start();
require 'config/database.php';

// 获取注册表单数据(表单提交时)
if(isset($_POST['submit'])){
    $fname = filter_var($_POST['fname'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $lname = filter_var($_POST['lname'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
    $username = filter_var($_POST['username'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $password = filter_var($_POST['password'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $confirm_passwd = filter_var($_POST['conf_passwd'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $avatar = $_FILES['avatar'];

    $errors = [];
    // 验证输入值
    if(empty($fname) || empty($lname) || empty($email) || empty($username) || empty($password) || empty($confirm_passwd) || empty($avatar)) {
        $errors['fname'] = "This field is required!";
        $errors['lname'] = "This field is required!";
        $errors['email'] = "This field is required!";
        $errors['username'] = "This field is required!";
        $errors['password'] = "This field is required!";
        $errors['conf_passwd'] = "This field is required!";
        $errors['avatar'] = "Please upload a file!";
    }

    // 其他验证信息将在单个错误信息正常显示后添加

    if (count($errors) > 0) {
        $_SESSION['signup-data'] = $_POST;
        $_SESSION['errors'] = $errors;
        header('Location: ' . ROOT_URL . 'signup.php');
        exit();
    }
} else {
    // 如果未提交表单,返回注册页面
    header('Location: ' . ROOT_URL . 'signup.php');
    exit();
}

signup.php

<?php
session_start();
require 'config/constants.php';

// 获取错误信息
$fname_errors = $_SESSION['errors']['fname'] ?? null;

// 出现错误时,将数据回填到输入框
$firstname = $_SESSION['signup-data']['fname'] ?? null;

// 如果没有问题,删除错误和注册数据会话
unset($_SESSION['signup-data']);
unset($_SESSION['errors']);
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Dynamic PHP Blog with MySQL and Admin Panel</title>
    <link type="text/css" rel="stylesheet" href="<?= ROOT_URL; ?>css/style.css">
</head>
<body>
<section class="form_section">
    <div class="container form_section-container">
        <h2>Sign Up</h2>
        <form automcomplete="off" action="<?= ROOT_URL; ?>register_func.php" method="post" enctype="multipart/form-data">
            <input type="text" name="fname" id="fname" placeholder="First Name" class="<?php if(isset($_SESSION['errors']['fname'])) echo 'hasError';?>" value="<?= $firstname; ?>">
            <?php if(isset($_SESSION['errors']['fname'])) : ?>
                <p><?= $_SESSION['errors']['fname']?></p>
            <?php endif; ?>
            <input type="text" name="lname" id="lname" placeholder="Last Name" class="" value="">
            
            <input type="text" name="email" id="email" placeholder="Email" class="" value="">
            
            <input type="text" name="username" id="username" placeholder="Username" class="" value="">
        
            <input type="password" name="password" id="password" placeholder="Password" class="" value="">
            
            <input type="password" name="conf_passwd" id="conf_passw" placeholder="Confirm Password" class="" value="">
            
            <div class="form_control">
                <label for="avatar">Use Avatar</label>
                <input type="file" name="avatar" id="avatar">
            </div>
            
            <button type="submit" name="submit" class="btn">Sign Up</button>
            <small>Already have an account? <a href="signin.php">Login</a></small>
        </form>
    </div>
</section>
</body>
</html>

验证错误截图

验证错误截图


问题分析与修正方案

核心问题

  1. 验证逻辑错误:用||同时判断所有字段,只要一个字段为空,就给所有字段添加错误信息,不符合“单独显示”的需求。
  2. 会话销毁时机错误:页面渲染前就销毁了$_SESSION['errors']和$_SESSION['signup-data'],导致渲染时拿不到数据。
  3. 错误显示不完整:只有名字字段做了错误处理,其他字段无对应逻辑。
  4. 文件上传验证不准确:empty($avatar)无法正确判断是否未上传文件,因为$_FILES即使无文件也会返回非空数组。

修正后的代码

register_func.php

<?php
session_start();
require 'config/database.php';

if(isset($_POST['submit'])){
    $fname = filter_var($_POST['fname'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $lname = filter_var($_POST['lname'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
    $username = filter_var($_POST['username'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $password = filter_var($_POST['password'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $confirm_passwd = filter_var($_POST['conf_passwd'], FILTER_SANITIZE_FULL_SPECIAL_CHARS);
    $avatar = $_FILES['avatar'];

    $errors = [];

    // 逐个字段验证,仅为空的字段添加错误
    if(empty($fname)) {
        $errors['fname'] = "名字不能为空!";
    }
    if(empty($lname)) {
        $errors['lname'] = "姓氏不能为空!";
    }
    if(empty($email)) {
        $errors['email'] = "邮箱不能为空!";
    }
    if(empty($username)) {
        $errors['username'] = "用户名不能为空!";
    }
    if(empty($password)) {
        $errors['password'] = "密码不能为空!";
    }
    if(empty($confirm_passwd)) {
        $errors['conf_passwd'] = "请确认密码!";
    }
    // 正确判断是否未上传文件
    if($avatar['error'] === UPLOAD_ERR_NO_FILE) {
        $errors['avatar'] = "请上传头像文件!";
    }

    // 可在此添加其他验证逻辑(如密码长度、邮箱格式等)

    if (count($errors) > 0) {
        $_SESSION['signup-data'] = $_POST;
        $_SESSION['errors'] = $errors;
        header('Location: ' . ROOT_URL . 'signup.php');
        exit();
    }
} else {
    header('Location: ' . ROOT_URL . 'signup.php');
    exit();
}

signup.php

<?php
session_start();
require 'config/constants.php';

// 一次性获取所有错误和表单数据
$errors = $_SESSION['errors'] ?? [];
$signupData = $_SESSION['signup-data'] ?? [];
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>动态PHP博客(带MySQL和后台管理)</title>
    <link type="text/css" rel="stylesheet" href="<?= ROOT_URL; ?>css/style.css">
    <style>
        .hasError { border: 1px solid #dc3545; }
        .error-text { color: #dc3545; margin: 5px 0 15px; padding: 0; font-size: 0.9em; }
    </style>
</head>
<body>
<section class="form_section">
    <div class="container form_section-container">
        <h2>注册</h2>
        <form autocomplete="off" action="<?= ROOT_URL; ?>register_func.php" method="post" enctype="multipart/form-data">
            <!-- 名字字段 -->
            <input type="text" name="fname" id="fname" placeholder="名字" 
                class="<?= isset($errors['fname']) ? 'hasError' : ''; ?>" 
                value="<?= htmlspecialchars($signupData['fname'] ?? '', ENT_QUOTES); ?>">
            <?php if(isset($errors['fname'])) : ?>
                <p class="error-text"><?= $errors['fname']; ?></p>
            <?php endif; ?>

            <!-- 姓氏字段 -->
            <input type="text" name="lname" id="lname" placeholder="姓氏" 
                class="<?= isset($errors['lname']) ? 'hasError' : ''; ?>" 
                value="<?= htmlspecialchars($signupData['lname'] ?? '', ENT_QUOTES); ?>">
            <?php if(isset($errors['lname'])) : ?>
                <p class="error-text"><?= $errors['lname']; ?></p>
            <?php endif; ?>

            <!-- 邮箱字段 -->
            <input type="email" name="email" id="email" placeholder="邮箱" 
                class="<?= isset($errors['email']) ? 'hasError' : ''; ?>" 
                value="<?= htmlspecialchars($signupData['email'] ?? '', ENT_QUOTES); ?>">
            <?php if(isset($errors['email'])) : ?>
                <p class="error-text"><?= $errors['email']; ?></p>
            <?php endif; ?>

            <!-- 用户名字段 -->
            <input type="text" name="username" id="username" placeholder="用户名" 
                class="<?= isset($errors['username']) ? 'hasError' : ''; ?>" 
                value="<?= htmlspecialchars($signupData['username'] ?? '', ENT_QUOTES); ?>">
            <?php if(isset($errors['username'])) : ?>
                <p class="error-text"><?= $errors['username']; ?></p>
            <?php endif; ?>

            <!-- 密码字段 -->
            <input type="password" name="password" id="password" placeholder="密码" 
                class="<?= isset($errors['password']) ? 'hasError' : ''; ?>" 
                value="<?= htmlspecialchars($signupData['password'] ?? '', ENT_QUOTES); ?>">
            <?php if(isset($errors['password'])) : ?>
                <p class="error-text"><?= $errors['password']; ?></p>
            <?php endif; ?>

            <!-- 确认密码字段 -->
            <input type="password" name="conf_passwd" id="conf_passwd" placeholder="确认密码" 
                class="<?= isset($errors['conf_passwd']) ? 'hasError' : ''; ?>" 
                value="<?= htmlspecialchars($signupData['conf_passwd'] ?? '', ENT_QUOTES); ?>">
            <?php if(isset($errors['conf_passwd'])) : ?>
                <p class="error-text"><?= $errors['conf_passwd']; ?></p>
            <?php endif; ?>

            <!-- 头像上传字段 -->
            <div class="form_control">
                <label for="avatar">上传头像</label>
                <input type="file" name="avatar" id="avatar">
                <?php if(isset($errors['avatar'])) : ?>
                    <p class="error-text"><?= $errors['avatar']; ?></p>
                <?php endif; ?>
            </div>

            <button type="submit" name="submit" class="btn">注册</button>
            <small>已有账号?<a href="signin.php">登录</a></small>
        </form>
    </div>
</section>
<?php
// 页面渲染完成后再销毁会话数据,避免渲染时丢失
unset($_SESSION['signup-data']);
unset($_SESSION['errors']);
?>
</body>
</html>

关键修正点

  • 逐个字段验证:替换原有的多字段或判断,改为每个字段单独检查,确保错误信息精准对应。
  • 调整会话销毁时机:将unset放在页面末尾,等所有内容渲染完成后再清除会话数据。
  • 统一错误显示:为所有字段添加错误样式和信息输出逻辑,同时用htmlspecialchars防止XSS注入。
  • 修复文件验证:使用UPLOAD_ERR_NO_FILE常量准确判断是否未上传文件。

内容的提问来源于stack exchange,提问作者Ismail9403

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 18:01:25