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

为什么继承validation类的子类中$errors和指定Session变量无法赋值?

问题根源
  1. 所有验证子类都重写了__construct构造方法,但既没有接收用户输入的$data参数,也没有主动调用父类validation的构造方法,导致子类实例的$user_data属性完全为空,验证逻辑的判断条件根本不会触发,自然不会设置$errors和对应的session变量。
  2. 你分别实例化了父类和3个子类,共4个完全独立的对象,子类产生的错误都存在各自实例的$errors属性里,你打印的$validation是父类实例,只会保存空字段检查的错误,看不到子类的验证错误。
  3. 父类validation的$errors属性没有初始化为空数组,首次追加错误时可能抛出PHP警告。
修复代码
<?php 
session_start();
class validation{
    public $user_data;
    // 初始化errors为空数组
    public $errors = [];

    public function __construct($data)
    {
        $this->user_data = $data;
        
        // 空字段检查
        foreach($this->user_data as $key => $value){
            if(empty($value)){
                $_SESSION["{$key}_empty"] = "set";
                $this->errors[] = "empty $key"; 
            }else{
                unset($_SESSION["{$key}_empty"]);
            }
        }
        // 存储输入值用于回显
        foreach($this->user_data as $key => $value){
            $_SESSION["{$key}_value"] = $value;
        }
    }
}  

// 子类构造接收data,调用父类构造
class email_validate extends validation{
    function __construct($data){
        // 先调用父类构造初始化user_data和空字段检查
        parent::__construct($data);
        if(!filter_var($this->user_data['email'], FILTER_VALIDATE_EMAIL)){
            $this->errors[] = "inval email";
            $_SESSION['inval email'] = 'set';
        }else{
            unset($_SESSION['inval email']);
        }
    }
}
class password_validate extends validation{
    function __construct($data){
        parent::__construct($data);
        if(strlen($this->user_data['password']) < 6){
            $this->errors[] = "inval password";
            $_SESSION['inval password'] = 'set';
        }else{
            unset($_SESSION['inval password']);
        }
    }
}
class repeat_password_validate extends validation{
    function __construct($data){
        parent::__construct($data);
        if($this->user_data['password'] !== $this->user_data['reppassword']){
            $this->errors[] = "inval repeat password";
            $_SESSION['inval rep password'] = 'set';
        }else{
            unset($_SESSION['inval rep password']);
        }
    }
}

$data = array(
    "email" => $_POST['email'], 
    "password" => $_POST['password'], 
    "reppassword" => $_POST['reppassword']
);

// 实例化各验证类时传入data
$emailValidation = new email_validate($data);
$passwordValidation = new password_validate($data);
$repPasswordValidation = new repeat_password_validate($data);

// 汇总所有错误
$allErrors = array_merge(
    $emailValidation->errors,
    $passwordValidation->errors,
    $repPasswordValidation->errors
);

echo "<pre>";
print_r($allErrors);
?>
更优写法推荐

你当前的写法会重复跑多次空字段检查逻辑,性能较差,建议把验证逻辑从构造方法里拆成独立的验证方法,用同一个实例跑所有验证即可:

<?php
session_start();
class validation{
    public $user_data;
    public $errors = [];

    public function __construct($data)
    {
        $this->user_data = $data;
        // 只跑一次空字段检查
        foreach($this->user_data as $key => $value){
            if(empty($value)){
                $_SESSION["{$key}_empty"] = "set";
                $this->errors[] = "empty $key"; 
            }else{
                unset($_SESSION["{$key}_empty"]);
            }
            $_SESSION["{$key}_value"] = $value;
        }
    }

    // 邮箱验证方法
    public function validateEmail(){
        if(!filter_var($this->user_data['email'], FILTER_VALIDATE_EMAIL)){
            $this->errors[] = "inval email";
            $_SESSION['inval email'] = 'set';
        }else{
            unset($_SESSION['inval email']);
        }
        return $this; // 支持链式调用
    }

    // 密码长度验证
    public function validatePassword(){
        if(strlen($this->user_data['password']) < 6){
            $this->errors[] = "inval password";
            $_SESSION['inval password'] = 'set';
        }else{
            unset($_SESSION['inval password']);
        }
        return $this;
    }

    // 重复密码验证
    public function validateRepeatPassword(){
        if($this->user_data['password'] !== $this->user_data['reppassword']){
            $this->errors[] = "inval repeat password";
            $_SESSION['inval rep password'] = 'set';
        }else{
            unset($_SESSION['inval rep password']);
        }
        return $this;
    }
}

$data = [
    'email' => $_POST['email'],
    'password' => $_POST['password'],
    'reppassword' => $_POST['reppassword']
];
$validator = new validation($data);
// 链式调用所有验证规则
$validator->validateEmail()
          ->validatePassword()
          ->validateRepeatPassword();

print_r($validator->errors);
?>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 19:45:06