PHP SESSION 取不到

窝最近在写一个注册的页面,需要邮箱验证的。窝的思路是这样的:

  • 按下发送按钮,就用 AJAX(原生的)请求 PHP 发送验证码。
  • PHP (参数 op=send_ve) 生成验证码,存到 $_SESSION 里面,然后把验证码发到用户邮箱。
  • 提交表单之后,PHP(同一个文件,参数 op=submit)比对验证码字段的内容和 $_SESSION 里面的,不一样就输出 “验证码错误!”

窝试了一下然后很尴尬的 “验证码错误” 了。然后在朋友的建议下试过各种方法:

  • session_start(); 放到页面最开始。
  • 用了一个固定的键名:"ve"(本来是用邮箱做)
  • 测试是不是所有的 $_SESSION 都不能用:

    • 于是我在发送验证码的地方加了一句 $_SESSION["OK"] = "OK";
    • 打印错误信息(“验证码错误”)的地方输出 $_SESSION
    • 啥也没输出,就一个空的 <p></p>

代码如下:

  • 前端 HTML,那个链接就是了。
  • 后端 PHP

          <?php session_start(); ?>
          <!DOCTYPE html>
          <html>
              <head>
                  <meta http-equiv="Content-type" content="text/html" charset="UTF-8"/>
                  <title>Mushouse - Sign up</title>
                  <link rel="stylesheet" type="text/css" href="https://icelava.ga/style.css">
                  <link rel="stylesheet" type="text/css" href="https://icelava.ga/fa/css/font-awesome.min.css">
                  <script type="text/javascript" src="https://icelava.ga/main.js"></script>
                  <script type="text/javascript" src="https://icelava.ga/marked.min.js"></script>
                  <script type="text/javascript" async src="https://cdn.bootcss.com/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
              </head>
              <body onload="init();">
                  <div id="guide"></div>
                  <p id="pos">Sign up</p>
                  <div id="main">
                      <div>
                          <p class="title">
                              <i class="fa fa-sign-in"></i> 注册信息
                          </p>
                          <?php
                              function echo_text($text)
                              {
                                  echo "<p class='text'>" . $text . "</p>";
                              }
          
                              function die_text($text)
                              {
                                  die("<p class='text'>" . $text . "</p>");
                              }
          
                              function qm_str($str)
                              {
                                  return "\"" . $str . "\"";
                              }
          
                              error_reporting(E_ALL);
                              header("Content-Type: text/html; charset=utf-8");
                              header("Access-Control-Allow-Origin: *");
                              header("Access-Control-Allow-Headers: Content-Type,Content-Length,Accept-Encoding,X-Requested-with, Origin");
          
                              use PHPMailer\PHPMailer\PHPMailer;
                              use PHPMailer\PHPMailer\Exception;
          
                              require "./PHPMailer/src/Exception.php";
                              require "./PHPMailer/src/PHPMailer.php";
                              require "./PHPMailer/src/SMTP.php";
          
                              try
                              {
                                  if ($_GET["op"] == "send_ve")
                                  {
                                      $ve = "";
                                      for ($i = 0; $i < 6; $i++)
                                          $ve .= mt_rand(0, 9);
                                      $_SESSION["ve"] = $ve;
          
                                      # Test:
                                      $_SESSION["OK"] = "OK";
          
                                      # Note: 开始发送邮件!
                                      $mail = new PHPMailer(true);
          
                                      $mail->CharSet = "UTF-8";
                                      $mail->SMTPDebug = 0;
                                      $mail->isSMTP();
                                      $mail->Host = "smtp.qq.com";
                                      $mail->SMTPAuth = true;
                                      $mail->Username = "fork_killet@qq.com";
                                      $mail->Password = "xxxx";
                                      $mail->SMTPSecure = "ssl";
                                      $mail->Port = 465;
                                      $mail->setFrom("fork_killet@qq.com", "IceLava 团队");
          
                                      echo $_POST["email"];
                                      $mail->addAddress($_POST["email"], $_POST["email"]);
          
                                      $mail->isHTML(true);
                                      $mail->Subject = "Mushouse 注册验证码";
                                      $mail->Body = "<b>这是 IceLava 团队向您发来的验证邮件,<br>如果不是您本人在注册 Mushouse 账户,请不要理睬!</b> <br>";
                                      $mail->Body .= "<p>6 位数字验证码:" . $ve . ",请在注册页面填写。</p> <br>";
                                      $mail->Body .= "<p>-- IceLava 团队</p>";
                                      $mail->AltBody = "很抱歉,您的邮箱太屑了,不支持 HTML 邮件内容!";
          
                                      $mail->send();
                                  }
                                  else if ($_GET["op"] == "submit")
                                  {
                                      if ($_POST["pw"] != $_POST["pw2"])
                                          echo_text("两次密码输入不一致!");
                                      else if (preg_match("/[^A-Za-z0-9_]/", $_POST["pw"]))
                                          echo_text("密码不能包含数字、大小写字母和下划线以外的字符!");
                                      else if (strlen($_POST["pw"]) < 6)
                                          echo_text("密码长度必须大于 6!");
                                      else if (strlen($_POST["pw"]) > 16)
                                          echo_text("密码长度必须小于 16!");
          
                                      else if (preg_match("/[^A-Za-z0-9_]/", $_POST["un"]))
                                          echo_text("用户名不能包含数字、大小写字母和下划线以外的字符!");
                                      else if (strlen($_POST["un"]) < 4)
                                          echo_text("用户名长度必须大于 4!");
                                      else if (strlen($_POST["un"]) > 16)
                                          echo_text("用户名长度必须小于 16!");
          
                                      else if (!preg_match("/^([A-Za-z0-9_\.\-])+\@(([A-Za-z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/", $_POST["email"]))
                                          echo_text("邮箱格式不正确!");
          
                                      # Note: 验证码检查
                                      else if ($_POST["ve"] != $_SESSION["ve"])
                                      {
                                          echo_text($_SESSION["ve"]);
                                          echo_text("验证码不正确!");
                                      }
          
                                      else
                                      {
                                          $conn = new mysqli("xxx", "xxx", "xxx", "icelavag");
                                          if ($conn->connect_error)
                                              die_text("数据库连接失败: " . $conn->connect_error);
          
                                          $rst = $conn->query
                                          (
                                              "SELECT * FROM user_info WHERE un=" . qm_str($_POST["un"])
                                          );
          
                                          if ($rst->num_rows == 1)
                                              echo_text("用户名 " . $_POST["un"] . " 已被注册!");
                                          else
                                          {
                                              $conn->query
                                              (
                                                  "INSERT INTO user_info (un, pw, email) VALUES (" .
                                                  qm_str($_POST["un"]) . ", " . qm_str($_POST["pw"]) . ", " . qm_str($_POST["email"]) . ")"
                                              );
                                              echo_text("注册成功!您可以去登陆了," . $_POST["un"] . " ~");
                                              echo_text($_SESSION["OK"]);
                                          }
                                      }
                                  }
                              }
                              catch(\Exception $err)
                              {
                                  echo_text($err->getMessage());
                              }
                          ?>
                      </div>
                  </div>
              </body>
          </html>
阅读 3.8k
3 个回答

我调试了两天终于找到了答案,似乎是 BOM 的原因(喷血)
但是各个工具都没能解决这个问题,说是没有 BOM
然后我自己手打了一遍就好了……

先看一下 PHP 是不是真的没写 Session,直接看 php.ini 里面的 session.save_path (默认/var/lib/php/session) 的位置是什么,如果 Session 目录啥也没有,检查一下文件夹的权限是否正确。
如果用的是 mem,redis,进去看一下有没有对应的 key

还有就是另一种可能,后端读取 cookies 的 PHPSESSID 读错了,检查一下浏览器的 cookies 是不是有两个 PHPSESSID ,把 cookies 删除了再试试

测试 Session 功能是否正常的时候,新开一个文件,写入 Session,然后再读一下

你提交的sign_up.php页面没写 session_start();吧

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题