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

PHP注册表单手机号/邮箱分支密码校验失效问题排查

PHP注册功能邮箱分支密码校验失效问题

问题背景

  • 基于PHP开发支持手机号、邮箱双模式的注册表单,核心校验逻辑通过IF/ELSE分支实现,两个分支设计上使用完全一致的密码长度校验规则(要求密码长度5~59位)
  • 异常表现:手机号注册分支的密码校验可正常触发,不符合长度要求的密码会被拦截;但邮箱注册分支下同规则的密码校验完全失效,仅输入1位字符的密码也可顺利完成注册
  • 已知正常逻辑:邮箱分支下的姓名长度拦截、邮箱已注册查重功能均可正常运行,问题为教程示例代码的原生缺陷,非二次开发引入的错误

问题相关原代码

require 'connect/DB.php';
require 'core/load.php';

if( isset($_POST['first-name']) && !empty($_POST['first-name']))
{
    $upFirst = $_POST['first-name'];
    $upLast = $_POST['last-name'];
    $upEmailMobile = $_POST['email-mobile'];
    $upPassword = $_POST['up-password'];
    $birthDay = $_POST['birth-day'];
    $birthMonth = $_POST['birth-month'];
    $birthYear = $_POST['birth-year'];    
    
    if(!empty($_POST['gen']))
    {
        $upgen = $_POST['gen'];
    }
    
    $birth = ''.$birthYear.'-'.$birthMonth.'-'.$birthDay.'';
    
    if(empty($upFirst) or empty($upLast) or empty($upEmailMobile) or empty($upgen))
    {
        $error = 'All fields are required';
    }
    else
    {
        $first_name = $loadFromUser->checkInput($upFirst);
        $last_name = $loadFromUser->checkInput($upLast);
        $email_mobile = $loadFromUser->checkInput($upEmailMobile);
        $password = $loadFromUser->checkInput($upPassword);
        $screenName = ''.$first_name.'_'.$last_name.'';
        
        if(DB::query('SELECT screenName FROM users WHERE screenName = :screenName', array(':screenName' => $screenName )))
        {    
            $screenRand = rand();
            $userLink = ''.$screenName.''.$screenRand.'';
        }
        else
        {
            $userLink = $screenName;
        }

        if(!preg_match("/^[_a-z0-9-]+(\.[_a-z0-9]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/",$email_mobile))
        {
            if(!preg_match("/^[0-9]{11}$/", $email_mobile))
            {
                $error = 'Email id or Mobile number is not correct. Please try again.';
            }
            else
            {
                $mob = strlen((string)$email_mobile);
                if($mob > 11 || $mob < 11)
                {
                    $error = 'Mobile number is not valid';
                }
                else if(strlen($password) <5 || strlen($password) >= 60)
                {
                    $error = 'Password is not correct';
                }
                else
                {
                    if(DB::query('SELECT mobile FROM users WHERE mobile=:mobile', array(':mobile'=>$email_mobile)))
                    {
                        $error = 'Mobile number is already in use.';
                    }
                    else
                    {
                        $user_id=$loadFromUser->create('users', array('first_name'=>$first_name,'last_name'=>$last_name, 'mobile' => $email_mobile, 'password'=>password_hash($password, PASSWORD_BCRYPT),'screenName'=>$screenName,'userLink'=>$userLink, 'birthday'=>$birth, 'gender'=>$upgen));
                        $loadFromUser->create('profile', array('userId'=>$user_id, 'birthday'=> $birth, 'firstName' => $first_name, 'lastName'=>$last_name, 'profilePic'=>'assets/image/defaultProfile.png','coverPic'=>'assets/image/defaultCover.png', 'gender'=>$upgen));
                        $tstrong = true;
                        $token = bin2hex(openssl_random_pseudo_bytes(64, $tstrong));
                        $loadFromUser->create('token', array('token'=>sha1($token), 'user_id'=>$user_id));
                        setcookie('FBID', $token, time()+60*60*24*7, '/', NULL, NULL, true);
                        header('Location: index.php');
                    }
                }
            }
        }
        else
        {
            // 存在缺陷的邮箱分支校验逻辑
            if(!filter_var($email_mobile))
            {
                $error = "Invalid Email Format";
            }
            else if(strlen($first_name) > 20)         
            {
                $error = "Name must be between 2-20 character";
            }
            else if(strlen($password) <5 || strlen($password) >= 60)
            {
                $error = "The password is either too short or too long";
            }
            else
            {
                if((filter_var($email_mobile,FILTER_VALIDATE_EMAIL)) && $loadFromUser->checkEmail($email_mobile) === true)
                {
                    $error = "Email is already in use";
                }
                else
                {
                    $user_id = $loadFromUser->create('users', array('first_name'=>$first_name,'last_name'=>$last_name, 'email' => $email_mobile, 'password'=>password_hash($password, PASSWORD_BCRYPT),'screenName'=>$screenName,'userLink'=>$userLink, 'birthday'=>$birth, 'gender'=>$upgen));
                    $loadFromUser->create('profile', array('userId'=>$user_id, 'birthday'=>$birth, 'firstName' => $first_name, 'lastName'=>$last_name, 'profilePic'=>'assets/image/defaultProfile.png','coverPic'=>'assets/image/defaultCover.png', 'gender'=>$upgen));
                    $tstrong = true;
                    $token = bin2hex(openssl_random_pseudo_bytes(64, $tstrong));
                    $loadFromUser->create('token', array('token'=>sha1($token), 'user_id'=>$user_id));
                    setcookie('FBID', $token, time()+60*60*24*7, '/', NULL, NULL, true);
                    header('Location: index.php');
                }
            }
        }
    }
}
?>

根因说明

  1. 核心问题:邮箱分支内第一个格式校验if(!filter_var($email_mobile))存在用法错误。filter_var()做邮箱格式校验时必须传入第二个参数FILTER_VALIDATE_EMAIL指定校验规则,漏传参数时函数会默认使用「原样返回输入值」的无过滤规则,导致该判断的返回值完全不符合预期,破坏了if-elseif的链式判断逻辑,后续的密码长度校验分支被直接跳过。
  2. 附加问题:姓名长度校验仅判断了长度大于20的非法场景,没有覆盖长度小于2的情况,和提示文案要求的2-20位长度规则不符。
  3. 正则不规范:原代码使用^作为正则分隔符、手机号正则缺少结尾锚定符,存在匹配绕过的风险。

修复方法

将邮箱分支的校验逻辑替换为如下代码即可,其余逻辑保持不变:

else
{
    // 补全filter_var的校验规则参数
    if(!filter_var($email_mobile, FILTER_VALIDATE_EMAIL))
    {
        $error = "Invalid Email Format";
    }
    // 补全姓名长度下限校验
    else if(strlen($first_name) > 20 || strlen($first_name) < 2)         
    {
        $error = "Name must be between 2-20 character";
    }
    else if(strlen($password) <5 || strlen($password) >= 60)
    {
        $error = "The password is either too short or too long";
    }
    else
    {
        // 移除重复的邮箱格式校验,仅保留查重逻辑
        if($loadFromUser->checkEmail($email_mobile) === true)
        {
            $error = "Email is already in use";
        }
        else
        {
            $user_id = $loadFromUser->create('users', array('first_name'=>$first_name,'last_name'=>$last_name, 'email' => $email_mobile, 'password'=>password_hash($password, PASSWORD_BCRYPT),'screenName'=>$screenName,'userLink'=>$userLink, 'birthday'=>$birth, 'gender'=>$upgen));
            $loadFromUser->create('profile', array('userId'=>$user_id, 'birthday'=>$birth, 'firstName' => $first_name, 'lastName'=>$last_name, 'profilePic'=>'assets/image/defaultProfile.png','coverPic'=>'assets/image/defaultCover.png', 'gender'=>$upgen));
            $tstrong = true;
            $token = bin2hex(openssl_random_pseudo_bytes(64, $tstrong));
            $loadFromUser->create('token', array('token'=>sha1($token), 'user_id'=>$user_id));
            setcookie('FBID', $token, time()+60*60*24*7, '/', NULL, NULL, true);
            header('Location: index.php');
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:21:23