PHP两步表单Session数据被覆盖致注册‘email不能为空’报错
问题分析与解决方案
你遇到的核心问题很明确:每次访问plz.php时,都会无条件执行顶部的Session赋值代码。当你提交第二步表单时,POST请求里只有第二步的下拉框数据(plz1),完全没有第一步的email、passwort等字段——这时候$_POST['email']会变成null(或未定义,取决于PHP配置),直接赋值给$_SESSION['email1']就会把之前从第一步存的有效数据覆盖掉,最终导致插入数据库时触发email cannot be null的错误。
下面是具体的修复步骤:
1. 给第一步的Session赋值添加条件判断
把顶部的Session赋值代码包裹在一个判断里,只有当第一步的POST数据存在时才执行(比如检查第一步的关键字段email或passwort是否存在):
// 只有从第一步addUser.php提交过来时,才初始化Session变量 if (isset($_POST['email']) && isset($_POST['passwort'])) { $_SESSION['email1'] = $_POST['email']; $_SESSION['passwort1'] = $_POST['passwort']; $_SESSION['vname1'] = $_POST['vname']; $_SESSION['fname1'] = $_POST['fname']; $_SESSION['phone1'] = $_POST['telnr']; $_SESSION['firma1'] = $_POST['firmen_name']; $_SESSION['ad11'] = $_POST['adresse1']; $_SESSION['ad21'] = $_POST['adresse2']; $_SESSION['kr1'] = $_POST['kreis']; }
这样当你提交第二步表单时,这些赋值代码不会执行,之前存在Session里的有效数据就不会被覆盖。
2. 在插入数据库前验证Session变量的有效性
为了避免Session失效、用户直接访问第二步页面等异常情况导致的空值,在执行INSERT之前,先检查所有需要的Session变量是否存在且不为空:
if(isset($_POST['submit'])){ // 先验证所有Session变量是否存在且非空 $requiredFields = ['email1', 'passwort1', 'vname1', 'fname1', 'phone1', 'firma1', 'ad11', 'ad21', 'kr1']; $missingFields = []; foreach($requiredFields as $field){ if(empty($_SESSION[$field])){ $missingFields[] = $field; } } if(!empty($missingFields)){ // 处理缺失数据的情况,比如跳回第一步或提示用户重新填写 die("Fehlende Registrierungsdaten: " . implode(', ', $missingFields)); } // 继续执行密码哈希和数据库插入逻辑 $hash = password_hash($_SESSION['passwort1'], PASSWORD_DEFAULT); $insert = "INSERT INTO users (email,passwort,vname,fname,firmen_name,telnr, userlevel, active, adresse1, adresse2, kreis, plz) VALUES (:email,:hash,:vname,:fname,:firma,:phone,1,0, :adresse1, :adresse2, :kreis, :plz)"; $prepStmt = $pdo->prepare($insert); $prepStmt ->bindParam("email", $_SESSION['email1']); $prepStmt ->bindParam("hash", $hash); $prepStmt ->bindParam("vname", $_SESSION['vname1']); $prepStmt ->bindParam("fname", $_SESSION['fname1']); $prepStmt ->bindParam("firma", $_SESSION['firma1']); $prepStmt ->bindParam("phone", $_SESSION['phone1']); $prepStmt ->bindParam("adresse1", $_SESSION['ad11']); $prepStmt ->bindParam("adresse2", $_SESSION['ad21']); $prepStmt ->bindParam("kreis", $_SESSION['kr1']); $prepStmt ->bindParam("plz", $_POST["plz1"]); $prepStmt ->execute(); // 插入成功后可以清空Session里的注册数据,避免重复提交 unset($_SESSION['email1'], $_SESSION['passwort1'], $_SESSION['vname1'], $_SESSION['fname1'], $_SESSION['phone1'], $_SESSION['firma1'], $_SESSION['ad11'], $_SESSION['ad21'], $_SESSION['kr1']); header("Location: users.php"); exit(); }
3. 可选:优化Session存储方式
如果觉得零散的Session变量不好维护,可以把第一步的所有数据存到一个Session数组里,更整洁也不容易出错:
// 第一步赋值时 if (isset($_POST['email']) && isset($_POST['passwort'])) { $_SESSION['reg_data'] = [ 'email' => $_POST['email'], 'passwort' => $_POST['passwort'], 'vname' => $_POST['vname'], 'fname' => $_POST['fname'], 'phone' => $_POST['telnr'], 'firma' => $_POST['firmen_name'], 'adresse1' => $_POST['adresse1'], 'adresse2' => $_POST['adresse2'], 'kreis' => $_POST['kreis'] ]; } // 插入时调用 $prepStmt ->bindParam("email", $_SESSION['reg_data']['email']); $prepStmt ->bindParam("hash", $hash); $prepStmt ->bindParam("vname", $_SESSION['reg_data']['vname']); // ... 其他参数同理
最后再确认一下:所有页面的session_start()都必须放在任何输出内容之前(包括HTML标签、空格等),否则Session无法正常工作。
内容的提问来源于stack exchange,提问作者ev_3
相关产品推荐
相关产品推荐

