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

PHP订单确认系统验证码验证失败问题求助

PHP订单确认系统验证码验证异常问题

我正在开发一款基于PHP的订单确认系统,当前遭遇验证码验证异常问题:验证码可成功生成并通过邮件发送给用户,但用户输入验证码进行验证时,系统无法识别其为正确代码。

相关代码

<?php
session_start();
if (!isset($_SESSION['user'])) {
    header('location:../connexion.php');
} else {
    require_once '../connectDB.php';

    if (isset($_GET['id'])) {
        $commandeId = $_GET['id'];

        $commande = $database->prepare("SELECT produits.idProduit, produits.nomProduit, produits.imageType, produits.image, commandeDetails.Quantite, produits.prixProduit FROM commandeDetails INNER JOIN produits ON commandeDetails.IDProduit = produits.idProduit WHERE IDCommande = :orderID");
        $commande->bindParam(":orderID", $commandeId);
        $commande->execute();

        if ($commande->rowCount() > 0) {
            $emailUser = $_SESSION['user']->email;
            require_once '../mail.php';
            // $verificationCode = 'ddec5800';
            $verificationCode = substr(md5(uniqid(mt_rand(), true)), 0, 8);
            $cmd = $database->prepare("UPDATE commandes SET verificationCode = :verificationCode WHERE idCommande = :commandeId");
            $cmd->bindParam(":verificationCode", $verificationCode);
            $cmd->bindParam(":commandeId", $commandeId);
            // $_SESSION['verification_code'] = $verificationCode;
            $cmd->execute();
            $verifCodeQuery = $database->prepare("SELECT verificationCode FROM commandes WHERE idCommande = :commandeId");
            $verifCodeQuery->bindParam(":commandeId", $commandeId);
            $verifCodeQuery->execute();
            $verificationCode = $verifCodeQuery->fetch(PDO::FETCH_COLUMN);

            $mail->addAddress($emailUser);
            $mail->Subject = "Confirmation de Commande - DRCoffee";
            $mail->Body = '
      
          
              
                  <h1>DRCoffee</h1>
              
              
                  <h2>Confirmation de Commande</h2>
                  <p>Merci de votre commande sur DRCoffee. Utilisez le code de vérification ci-dessous pour confirmer votre commande :</p>
                  <h3>Code de Vérification: ' . $verificationCode . '</h3>
                  <p>Entrez ce code lors du processus de confirmation de commande.</p>
                  <p>Merci de choisir DRCoffee!</p>
                  <p>L\'équipe DRCoffee</p>
              
              
                  <p>DRCoffee - Casablanca, Maroc</p>
              
          
      ';
            $mail->setFrom("oyuncoyt@gmail.com", "DRCoffee");
            $mail->send();
        }

        if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['verification'])) {
            $verife = $database->prepare('SELECT verificationCode FROM commandes WHERE idCommande = :commandeId');
            $verife->bindParam(":commandeId", $commandeId);
            $verife->execute();
            $code = $verife->fetch(PDO::FETCH_COLUMN);
            if ($_POST['verification_code'] == $code) {
                $updateStock = $database->prepare("UPDATE produits SET stock = stock - :quantitySold WHERE idProduit = :productId");

                while ($commandeDetails = $commande->fetch(PDO::FETCH_ASSOC)) {
                    $productId = $commandeDetails['idProduit'];
                    $quantitySold = $commandeDetails['Quantite'];

                    $updateStock->bindParam(":quantitySold", $quantitySold);
                    $updateStock->bindParam(":productId", $productId);
                    $updateStock->execute();
                }

                $commande->execute();

                $updateStatus = $database->prepare("UPDATE commandes SET etat = 'Confirmée' WHERE idCommande = :orderId");
                $updateStatus->bindParam(":orderId", $commandeId);
                $updateStatus->execute();

                header('Location: confirmation-success.php');
                exit();
            } else {
                header('Location: about.php');
                exit();
            }
        }
    }
?>

已尝试的排查步骤

  • 确认验证码已成功生成并存储至数据库;
  • 验证邮件已正确发送给用户且包含正确验证码;
  • 确认用户在验证过程中输入的代码无误;
  • 检查数据库,确认验证码可被正确调取用于比对;
  • 检查验证流程执行过程中是否存在错误信息或异常。

当前疑问

  1. 我的验证码逻辑是否存在潜在漏洞?
  2. 邮件内容发送是否正确,是否会影响验证流程?
  3. 有哪些调试建议可用于定位验证流程的失败环节?

期望结果

用户输入的验证码可与数据库中存储的代码匹配,完成订单确认,但目前输入正确代码仍无法通过验证,恳请提供解决思路与建议。


解决思路与建议

一、验证码逻辑的潜在漏洞排查

  1. POST请求结果集指针耗尽问题
    页面加载时已执行$commande->execute()并读取过订单详情,POST验证通过后再次调用while ($commandeDetails = $commande->fetch(...))时,PDO结果集指针已处于末尾,无法获取数据。虽然不直接影响验证码验证,但会导致库存更新失败,甚至引发后续异常。建议在POST分支重新执行订单查询,或提前将结果存入数组:

    // POST分支内重新查询订单详情
    $commande = $database->prepare("SELECT produits.idProduit, commandeDetails.Quantite FROM commandeDetails INNER JOIN produits ON commandeDetails.IDProduit = produits.idProduit WHERE IDCommande = :orderID");
    $commande->bindParam(":orderID", $commandeId);
    $commande->execute();
    
  2. 松散比对的风险
    当前使用==松散比对,若数据库中验证码为字符串、用户输入被解析为其他类型(如数字),可能出现匹配异常。改用===进行严格类型+值比对:

    if ($_POST['verification_code'] === $code) {
        // 验证通过逻辑
    }
    
  3. 页面刷新导致验证码覆盖
    每次GET请求都会重新生成并更新数据库验证码,若用户多次刷新页面,数据库中验证码会被覆盖,用户收到的旧邮件验证码自然无法匹配。添加判断,仅当订单无验证码时才生成发送:

    $checkCode = $database->prepare("SELECT verificationCode FROM commandes WHERE idCommande = :commandeId");
    $checkCode->bindParam(":commandeId", $commandeId);
    $checkCode->execute();
    $existingCode = $checkCode->fetch(PDO::FETCH_COLUMN);
    if (empty($existingCode)) {
        // 生成并发送验证码的逻辑
    }
    

二、邮件内容对验证流程的影响

从代码看,邮件验证码直接取自数据库,不会直接导致验证失败,但需注意两点:

  • 检查HTML渲染是否产生不可见字符:比如<h3>标签的样式是否导致验证码前后出现空格,可在邮件中添加纯文本版本的验证码,或提示用户复制纯文本内容。
  • 确认邮件发送时未对验证码进行转义/编码,避免实际发送内容与数据库存储不一致。

三、调试建议

  1. 输出比对的具体值
    在POST验证分支临时添加代码,直观查看用户输入与数据库取出的验证码细节:

    // POST分支内
    var_dump($_POST['verification_code'], $code);
    exit;
    

    可排查空格、大小写、字符编码等差异。

  2. 开启PHP错误提示
    在代码开头添加,捕获未处理的PDO错误或变量异常:

    error_reporting(E_ALL);
    ini_set('display_errors', 1);
    
  3. 核对表单参数名
    确认前端输入框的name属性为verification_code,与后端$_POST['verification_code']完全一致,避免拼写错误。

  4. 验证订单ID的有效性
    确认POST请求时$commandeId正确,比如表单中通过隐藏域传递订单ID,避免因ID错误查询到无关验证码。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 23:20:55