有没有更好的方法然后使用多个if条件?

时间:2011-05-12 05:55:21

标签: php

我有一个php类方法,它确定一个类属性是否有任何值。如果它包含任何值,那么它将验证并迭代$ this->错误类属性。这是我正在使用的类方法。

public function validate() {
    if(!empty($this->name)) {
        if(!preg_match('/^[a-zA-z ]{3,50}$/',$this->name)) {
            $this->error['name'] = 'Name should be valid letters and should be between 3 and 25 characters';
        }
    }
    if(!empty($this->email)) {
        if(!filter_var($this->email,FILTER_VALIDATE_EMAIL)) {
            $this->error['invalidEmail'] = 'Invalid email address';
        }
        if(empty($this->userId) && $this->emailCount($this->email)) {
            $this->error['emailExist'] = 'Email already exist';
        }
    }
    if(empty($this->userId) && !empty($this->password)) {
        if(strlen($this->password) < 5 || strlen($this->password > 40)) {
            $this->error['password'] = 'Password length should be between 5 and 40 characters';
        }
    }
    if(!empty($this->userId) && !empty($this->newPassword)) {
        if(strlen($this->newPassword) < 5 || strlen($this->newPassword > 40)) {
            $this->error['password'] = 'Password length should be between 5 and 40 characters';
        }
    }
    if(!empty($this->pPhone)) {
        if(!preg_match('/^[0-9]{5,10}$/',$this->pPhone)) {
            $this->error['invalidpPhone'] = 'Invalid primary phone number';
        }
    }
    if(!empty($this->sPhone)) {
        if(!preg_match('/^[0-9]{5,10}$/',$this->sPhone)) {
            $this->error['invalidsPhone'] = 'Invalid secondary phone number';
        }
    }
    return (empty($this->error)) ? true : false;    
}

我已经在这里使用了很多if条件我认为不是很好,有没有其他方法可以确定上述条件并以更好的方式重写代码?

6 个答案:

答案 0 :(得分:3)

您可以使用变量并循环遍历代码。但这意味着你必须为你的代码提出某种标准化的验证方案

$validateFields = array('email', 'username', 'userId'); //list of fields to validate
$rules = array(
  'username' => array('type'=> 'regex', 'rule' => '/^[a-zA-z ]{3,50}$/'),
  'email'    => array('type' => 'filter', 'rule' => 'FILTER_VALIDATE_EMAIL')
);

foreach ($validateFields as $field) {
   if (isset($rules[$field])) {
       switch ($rules[$field]['type']) {
           case 'regex' : 
              if(!preg_match($rules[$field]['type']['rule'],$this->$field)) {
                    $this->error[$field] = ucfirst($field) . ' should be valid letters and should be between 3 and 25 characters';
              }
              break;

           case 'filter' :
              if(!filter_var($this->$field, $rules[$field]['type']['rule'])) {
                  $this->error[$field] = 'Invalid email address';
              }
              break

           //more cases
       }
   }
}
return (empty($this->error)) ? true : false; 

此示例每个字段仅使用一个规则,但您应该能够轻松扩展它以使用每个字段的多个规则。

您最初必须设置所有规则,但验证不会因为您向类中添加其他属性而增长。

答案 1 :(得分:1)

我认为你不能以更好的方式重写这个特定的片段代码。

但是,从更大的图片来看,可能会有所改进。查看类变量,这可能是表单类或某些类型的模型实例,并且您在保存数据之前尝试验证数据。您可以在单独的类中概括和抽象验证逻辑。如需灵感,请查看各种PHP框架(例如Symphony,CakePHP)如何处理表单和模型验证。

答案 2 :(得分:1)

首先,您应该将错误字符串提取到定义或更好的类常量中。

define('ERR_BAD_NAME','Name should be valid letters and should be between 3 and 25 characters');
define('ERR_BAD_EMAIL','Invalid email address');
define('ERR_EMAIL_IN_USE','Email already exist');
define('ERR_BAD_PASSWD','Password length should be between 5 and 40 characters');
define('ERR_BAD_PRIMARY_PHONE','Invalid primary phone number');
define('ERR_BAD_SECONDARY_PHONE','Invalid primary phone number');

public function validate() {
    if(!empty($this->name)) {
        if(!preg_match('/^[a-zA-z ]{3,50}$/',$this->name)) {
            $this->error['name'] = ERR_BAD_NAME;
        } 
    }
    if(!empty($this->email)) {
        if(!filter_var($this->email,FILTER_VALIDATE_EMAIL)) {
            $this->error['invalidEmail'] = ERR_BAD_EMAIL;
        }
        if(empty($this->userId) && $this->emailCount($this->email)) {
            $this->error['emailExist'] = ERR_EMAIL_IN_USE;
        }
    }
    if(empty($this->userId) && !empty($this->password)) {
        if(strlen($this->password) < 5 || strlen($this->password > 40)) {
            $this->error['password'] = ERR_BAD_PASSWD;
        }
    }

    if(!empty($this->pPhone)) {
        if(!preg_match('/^[0-9]{5,10}$/',$this->pPhone)) {
            $this->error['invalidpPhone'] = ERR_BAD_PRIMARY_PHONE;
        }
    }
    if(!empty($this->sPhone)) {
        if(!preg_match('/^[0-9]{5,10}$/',$this->sPhone)) {
            $this->error['invalidsPhone'] = ERR_BAD_PRIMARY_PHONE;
        }
    }
    return (empty($this->error)) ? true : false;    
}

第二步是将测试重构为单独的私有方法,并删除if块:

private function validate_name($name) {
    return = empty($name) || preg_match('/^[a-zA-z ]{3,50}$/',$name);
}

private function validate_phone($phone) {
    return empty($phone) || preg_match('/^[0-9]{5,10}$/',$phone);
}

private function validate_email($email) {
   return empty($email)) || filter_var($email,FILTER_VALIDATE_EMAIL);
}

private function emailInUse($email, $userId) {
   if(!empty($email)) {
        if(empty($this->userId) && $this->emailCount($this->email)) {
            $this->error['emailExist'] = ERR_EMAIL_IN_USE;
        }
    }
}

private function validate_userPassword($userId, $password) {
    $passwordLen=strlen($this->password);
    return (empty($this->userId) && !empty($this->password)) ||
           (5 <= $passwordLen) && (40 >= $passwordLen); 
}

private function lor_error($type, $message) {
    $this->error[$type] = $message;
    return false;
}

public function validate() {
  $isValid = true;
  $isValid &= $this->validate_name($this->name) || 
              $this->logError('name',ERR_BAD_NAME);
  $isValid &= $this->validate_email($this->email) || 
              $this->logError('invalidEmail',ERR_BAD_EMAIL);
  $isValid &= $this->emailInUse($this->userId, $this->email) || 
              $this->logError('emailExist',ERR_EMAIL_IN_USE);
  $isValid &= $this->validateUserPassword($this->userId, $this->password) ||
              $this->log('password', ERR_BAD_PASSWD);
  $isValid &= $this->validate_phone($this->pPhone) ||
              $this->log('invalidpPhone',ERR_BAD_PRIMARY_PHONE);
  $isValid &= $this->validate_phone($this->sPhone) ||
              $this->log('invalidsPhone',ERR_BAD_SECONDARY_PHONE);
  return $isValid;
}

在第三个重构阶段,您应该将validate_ *方法提取到验证器类中,以从主类中分离验证任务。后一阶段显然取决于您(作为定义正确日志类的负担)。

答案 3 :(得分:0)

如果你想使用if条件你可以使用if case

的select case

线 情况1   如果阻止

案例2    如果阻止

如果能以更好的方式帮助你

答案 4 :(得分:0)

我不认为您可以避免这种多重If语句,因为我看到是您验证字段的位置。

multimple if语句的其他替代方法是 Swtich语句

我不确定这种情况是否可行,因为你将String作为参数传递,而Switch不会将String作为参数,它只需要整数作为输入

答案 5 :(得分:0)

这是一个更简洁的代码解决方案的模型,我没有编译它,因为它不是我生活中的工作,但它绝对是你想要的路径,因为你有太多的重复自己你的代码。

但是,这是非常接近你现在正在做的事情,我只是丢失了一些身份证检查和其他各种代码,你必须重新实施。

另外,我这样做是假设这已经在一个类中,并且你正在访问类变量$this->name

<?php 

public function validate() {
    //You can place your simple ID checks around these wherever they're supposed to go, I lost them ;P.
    //This code probably won't compile without errors, but it's to give you a much neater idea.
    //Never ever repeat code !!! Your life becomes so much better :]
    $this->validate_name($this->name);
    $this->validate_email($this->email); // I didn't complete this one.. but this is just all for an idea


    $this->validate_phone_number($this->pPhone,'Primary');
    $this->validate_phone_number($this->sPhone,'Secondary');

    return (empty($this->error)) ? true : false;    
}

function validate_password($password){
    !empty($password)) {
        if(strlen($password) < 5 || strlen($password > 40)) {
            $this->error['password'] = 'Password length should be between 5 and 40 characters';
        }
}

function validate_name($name){
        if(!preg_match('/^[a-zA-z ]{3,50}$/',$name)) {
            $this->error['name'] = 'Name should be valid letters and should be between 3 and 25 characters';
        }
}

function validate_phone_number($number,$type){
    if(!preg_match('/^[0-9]{5,10}$/',number)) {
            $this->error['invalidsPhone'] = "Invalid $type phone number";
        }
}