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

电商网站PHP Session无法正常工作的技术求助

电商网站会话问题排查与修复

问题描述

我正在搭建一个电商网站项目,初期就遇到了持续的问题:session_start()似乎无法正常工作或无法显示会话内容。我尝试了多种解决方法,最后甚至照搬了YouTube上PacketCode的教程代码,但浏览器仍无预期结果。我原本期望登录后能正常显示会话相关内容,但参考大量代码后问题仍未解决,完全无从下手。

相关代码文件

index.php

<?php
    session_start();
    include "db.php";
    include "retrieve.php";
    include "function.php";
    include "logic.php";
?>
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Exquisite</title>
</head>
<body>
    <div class="container" id="main_cntr">
        <div id="intro_cntr">
            <div id="title_cntr">
                <h2>Welcome to </h1>
                <h1>Exquisite</h1>
            </div>
            <div id="paragraph_cntr">
                <p>Here to provide an excellent support for your style!</p>
            </div>
        </div>

        <?php if(empty($_SESSION['username'])){?>
        <div class="container" id="form">
            <div id="login_cntr">
                <form method="POST">
                    <h2>Login</h2>
                    <label for="username">Username</label><br>
                    <input type="text" name="username" placeholder="Enter your Username"><br>
                    <label for="password">Password</label><br>
                    <input type="password" name="pass" placeholder="Enter your Password"><br>
                    <input type="submit" name="login" value="Login">
                </form>
            </div>
        <?php }?>
        
        <div id="signupOption_cntr">
                <a href="signup(user).php">Create an Account</a>
                <h4>or</h4>
                <a href="login(admin).php">Login as Admin</a>
            </div>  
        </div>

        <?php if(!empty($_SESSION['username'])){?>
            <div class="container">
                <h1>Hello again<?php echo $_SESSION['username'];?></h1>
                <form method="POST">
                     <button name="logout">Logout</button>
                </form>
            </div>
        <?php }?>
         
    </div>
</body>
</html>

db.php

<?php
$conn = mysqli_connect('localhost', 'root', '', 'exquisite') or die ("Cannot connect to the Database");
?>

retrieve.php

<?php
    if(isset($_REQUEST['login'])){
        $uname = $_REQUEST['username'];
        $pword = $_REQUEST['pass'];
    }
?>

function.php

<?php
    function login($conn, $uname, $pword){
        $sql = "SELECT * FROM `user_acc` WHERE `username` = '$uname'";
        $query = mysqli_query($conn, $sql);
        return $query;
    }
?>

logic.php

<?php
    if(isset($_REQUEST['login'])){
        $result = login($conn, $uname, $pword);

        foreach($result as $r){
            $passw_check = password_verify($pword, $r['password']);

            if($passw_check){
                $_SESSION['username'] = $r['username'];
                header("location: home.php");
            }
        }
    }

    if(isset($_REQUEST['logout'])){
        session_destroy();
        header("location: index.php");
        exit();
    }
?>

问题根源与修复方案

1. 变量作用域问题

retrieve.php中定义的$uname和$pword仅在自身的if(isset($_REQUEST['login']))代码块内有效,logic.php的同名代码块无法访问这些变量,会直接触发未定义变量错误,导致登录逻辑完全无法执行。

修复:直接在logic.php中获取表单数据,删除retrieve.php(或调整其逻辑):

// logic.php 修正后
if(isset($_POST['login'])){
    // 直接从POST获取变量,同时做基础过滤
    $uname = trim($_POST['username']);
    $pword = trim($_POST['pass']);
    
    $result = login($conn, $uname, $pword);
    // ... 后续逻辑
}

2. SQL注入风险

function.php中的SQL语句直接拼接用户输入,存在严重的SQL注入漏洞,同时也可能因输入含特殊字符导致查询失败。

修复:使用MySQLi预处理语句重构login函数:

// function.php 修正后
function login($conn, $uname){
    // 仅查询需要的字段,避免返回不必要数据
    $sql = "SELECT username, password FROM `user_acc` WHERE `username` = ?";
    $stmt = mysqli_prepare($conn, $sql);
    mysqli_stmt_bind_param($stmt, "s", $uname);
    mysqli_stmt_execute($stmt);
    $result = mysqli_stmt_get_result($stmt);
    return $result;
}

3. 跳转后未终止脚本执行

登录成功后调用header("location: home.php")但未加exit(),后续代码仍可能执行,导致会话设置被意外覆盖或干扰。

修复:跳转后立即终止脚本:

if($passw_check){
    $_SESSION['username'] = $r['username'];
    header("location: home.php");
    exit(); // 必须添加,终止后续代码执行
}

4. 目标页面未启动会话

跳转的home.php如果没有调用session_start(),将无法读取已设置的会话变量,导致页面无法识别登录状态。

修复:在home.php顶部添加:

<?php
session_start();
// 检查会话是否有效,若未登录则跳转回登录页
if(empty($_SESSION['username'])){
    header("location: index.php");
    exit();
}
?>

5. 会话输出缓冲问题

如果session_start()之前有任何输出(包括空格、HTML标签),会导致会话无法正常启动。检查所有PHP文件的开头,确保<?php标签前没有空白字符,且没有提前输出内容。

最终修正后的logic.php完整代码

<?php
    if(isset($_POST['login'])){
        $uname = trim($_POST['username']);
        $pword = trim($_POST['pass']);
        
        $result = login($conn, $uname);
        // 使用mysqli_fetch_assoc而非foreach遍历结果
        $user = mysqli_fetch_assoc($result);
        
        if($user && password_verify($pword, $user['password'])){
            $_SESSION['username'] = $user['username'];
            header("location: home.php");
            exit();
        } else {
            // 可添加登录失败提示
            $_SESSION['error'] = "用户名或密码错误";
        }
    }

    if(isset($_REQUEST['logout'])){
        session_destroy();
        // 销毁会话后建议清除会话Cookie
        if(isset($_COOKIE[session_name()])){
            setcookie(session_name(), '', time()-3600, '/');
        }
        header("location: index.php");
        exit();
    }
?>

内容的提问来源于stack exchange,提问作者IT-boi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 18:25:18