Php 嵌套ifs以捕获错误

Php 嵌套ifs以捕获错误,php,if-statement,Php,If Statement,你可能知道这幅图: 假设我想通过各种方法验证单个用户输入,而每种方法都取决于前一种方法的成功。如果筑巢,我怎样才能避免这种不规则和丑陋 我想不出其他方法,可以正确验证并在发生错误时返回正确的消息,但它看起来确实很难看,可能会让mantain感到痛苦 有什么想法吗?您可以使用try/catch块,在验证失败时抛出异常。例如: try { if (!$_POST['user_name']) { throw new Exception('Invalid username'); }

你可能知道这幅图:

假设我想通过各种方法验证单个用户输入,而每种方法都取决于前一种方法的成功。如果筑巢,我怎样才能避免这种不规则和丑陋

我想不出其他方法,可以正确验证并在发生错误时返回正确的消息,但它看起来确实很难看,可能会让mantain感到痛苦


有什么想法吗?

您可以使用try/catch块,在验证失败时抛出异常。例如:

try {
  if (!$_POST['user_name']) {
    throw new Exception('Invalid username');
  }

  if (!$_POST['user_password_new']) {
    throw new Exception('Invalid password');
  }

} catch (Exception $e) {
  echo 'Caught exception: ',  $e->getMessage(), "\n";
}
function isFormPopulated() {
    $requiredFields = array('user', 'pass', 'age', 'sex');
    foreach ($requiredFields as $field) {
        if (empty($_POST[$field])) { 
            $_SESSION['msg'] = $field . ' field should be populated'; // here better throw exception, instead of session saving the message
            return false;
        }
    }
    return true;
}

function isPatternValid() {
     $fieldPatterns = array('user' => '/w+/', 'pass' => 'someOtherRegex')
     foreach ($fieldPatterns as $field => $pattern) {
         if (!preg_match($pattern, $_POST[$field])) {
             return false;
         }
     }
     return true;
}

function isUserAllowed() {
    if (in_array($_SERVER['REMOTE_ADDR']......) {
        return false;
    }
    return true;
}

function isUserLegal() {
    if ($_POST['age'] < self::MIN_ALLOWED_AGE) {
        return false;
    }
    return true;
}

function isValid() {
     // here you can check with && the evaluation of the previous functions
     // or you can check one by one and return false aswell
     // return true at the end
}


function register() {
     if (!isValid()) {
         return false;
     }
     // continue execution of the registration process
}

您可以使用try/catch块,并在验证失败时抛出异常。例如:

try {
  if (!$_POST['user_name']) {
    throw new Exception('Invalid username');
  }

  if (!$_POST['user_password_new']) {
    throw new Exception('Invalid password');
  }

} catch (Exception $e) {
  echo 'Caught exception: ',  $e->getMessage(), "\n";
}
function isFormPopulated() {
    $requiredFields = array('user', 'pass', 'age', 'sex');
    foreach ($requiredFields as $field) {
        if (empty($_POST[$field])) { 
            $_SESSION['msg'] = $field . ' field should be populated'; // here better throw exception, instead of session saving the message
            return false;
        }
    }
    return true;
}

function isPatternValid() {
     $fieldPatterns = array('user' => '/w+/', 'pass' => 'someOtherRegex')
     foreach ($fieldPatterns as $field => $pattern) {
         if (!preg_match($pattern, $_POST[$field])) {
             return false;
         }
     }
     return true;
}

function isUserAllowed() {
    if (in_array($_SERVER['REMOTE_ADDR']......) {
        return false;
    }
    return true;
}

function isUserLegal() {
    if ($_POST['age'] < self::MIN_ALLOWED_AGE) {
        return false;
    }
    return true;
}

function isValid() {
     // here you can check with && the evaluation of the previous functions
     // or you can check one by one and return false aswell
     // return true at the end
}


function register() {
     if (!isValid()) {
         return false;
     }
     // continue execution of the registration process
}

一个好的做法是防止语句嵌套太深。所以最好找到负面的情况,马上处理。例如:

if(!$_POST['user_name']){
    // exit
}

if(!$_POST['password']){
    // exit
}

// if we get to here, we assume all previous checks passed

这将创建干净的代码,因为深度嵌套的代码更难维护,并且在找到条件后立即处理它们

一个好的做法是防止语句嵌套太深。所以最好找到负面的情况,马上处理。例如:

if(!$_POST['user_name']){
    // exit
}

if(!$_POST['password']){
    // exit
}

// if we get to here, we assume all previous checks passed

这将创建干净的代码,因为深度嵌套的代码更难维护,并且在找到条件后立即处理它们

根据下面的语句,您似乎可以将它们堆叠起来,如果前一个失败,则立即返回。如果上一次检查成功,则可以安全地执行下一次检查

每一个都取决于前一个的成功


根据下面的语句,似乎可以将它们堆叠起来,如果前一个失败,则立即返回。如果上一次检查成功,则可以安全地执行下一次检查

每一个都取决于前一个的成功


到目前为止,我的经验表明,如果你对同一个目标进行了4-5次以上的验证,那么你很可能做错了什么。为了验证用户输入,您可能需要特定的字符模式,这可以通过regex实现,您可能需要填充所有字段,例如用户来自特定国家/地区IP或在下拉列表中至少检查了18岁。所有其他的事情,无论是对这些人来说,还是机会,都是多余的

正如其他人所说,您也不应该嵌套块,而是在不满足条件时返回执行

例如:

try {
  if (!$_POST['user_name']) {
    throw new Exception('Invalid username');
  }

  if (!$_POST['user_password_new']) {
    throw new Exception('Invalid password');
  }

} catch (Exception $e) {
  echo 'Caught exception: ',  $e->getMessage(), "\n";
}
function isFormPopulated() {
    $requiredFields = array('user', 'pass', 'age', 'sex');
    foreach ($requiredFields as $field) {
        if (empty($_POST[$field])) { 
            $_SESSION['msg'] = $field . ' field should be populated'; // here better throw exception, instead of session saving the message
            return false;
        }
    }
    return true;
}

function isPatternValid() {
     $fieldPatterns = array('user' => '/w+/', 'pass' => 'someOtherRegex')
     foreach ($fieldPatterns as $field => $pattern) {
         if (!preg_match($pattern, $_POST[$field])) {
             return false;
         }
     }
     return true;
}

function isUserAllowed() {
    if (in_array($_SERVER['REMOTE_ADDR']......) {
        return false;
    }
    return true;
}

function isUserLegal() {
    if ($_POST['age'] < self::MIN_ALLOWED_AGE) {
        return false;
    }
    return true;
}

function isValid() {
     // here you can check with && the evaluation of the previous functions
     // or you can check one by one and return false aswell
     // return true at the end
}


function register() {
     if (!isValid()) {
         return false;
     }
     // continue execution of the registration process
}

到目前为止,我的经验表明,如果你对同一个目标进行了4-5次以上的验证,那么你很可能做错了什么。为了验证用户输入,您可能需要特定的字符模式,这可以通过regex实现,您可能需要填充所有字段,例如用户来自特定国家/地区IP或在下拉列表中至少检查了18岁。所有其他的事情,无论是对这些人来说,还是机会,都是多余的

正如其他人所说,您也不应该嵌套块,而是在不满足条件时返回执行

例如:

try {
  if (!$_POST['user_name']) {
    throw new Exception('Invalid username');
  }

  if (!$_POST['user_password_new']) {
    throw new Exception('Invalid password');
  }

} catch (Exception $e) {
  echo 'Caught exception: ',  $e->getMessage(), "\n";
}
function isFormPopulated() {
    $requiredFields = array('user', 'pass', 'age', 'sex');
    foreach ($requiredFields as $field) {
        if (empty($_POST[$field])) { 
            $_SESSION['msg'] = $field . ' field should be populated'; // here better throw exception, instead of session saving the message
            return false;
        }
    }
    return true;
}

function isPatternValid() {
     $fieldPatterns = array('user' => '/w+/', 'pass' => 'someOtherRegex')
     foreach ($fieldPatterns as $field => $pattern) {
         if (!preg_match($pattern, $_POST[$field])) {
             return false;
         }
     }
     return true;
}

function isUserAllowed() {
    if (in_array($_SERVER['REMOTE_ADDR']......) {
        return false;
    }
    return true;
}

function isUserLegal() {
    if ($_POST['age'] < self::MIN_ALLOWED_AGE) {
        return false;
    }
    return true;
}

function isValid() {
     // here you can check with && the evaluation of the previous functions
     // or you can check one by one and return false aswell
     // return true at the end
}


function register() {
     if (!isValid()) {
         return false;
     }
     // continue execution of the registration process
}

默认情况下,您应该简化验证。最有可能的情况是,您不需要超过2次检查来完全确保用户失败。你可以在每个错误后返回,你不需要继续,你应该在默认情况下简化验证。最有可能的情况是,您不需要超过2次检查来完全确保用户失败。还有两个以上的其他字段以确保没有问题。每次出现错误后,您只需返回,不需要继续。因此,最后您有20个if,这与图片中的相同?@RoyalBg是的,但它们不是嵌套的。如果检查N个字段是否为空是条件,为什么不保留一个带有字段名称和相应消息的映射,只需在循环中检查其中一个键是否为空,即可返回其映射消息?@RoyalBg再次阅读问题。OP说:“通过各种方法验证单个用户的输入”。在这种情况下,
foreach
不会有帮助。这段代码只是一个例子,让OP知道如何做。那么,为什么不每个方法检查前面的成功,例如
validPassword()
方法检查
emptyFields()&&strlen(…)>N
emptyFields()
检查
其他依赖条件()&&empty(…)
,然后在
寄存器()中
只调用了一个
isValid()
方法,该方法调用链中的最后一个方法?因此,最后您有20个if,与图片中的相同?@RoyalBg是的,但它们没有嵌套。如果检查N个字段是否为空是条件,为什么不保留一个带有字段名称和相应消息的映射,只需在循环中检查其中一个键是否为空,即可返回其映射消息?@RoyalBg再次阅读问题。OP说:“通过各种方法验证单个用户的输入”。在这种情况下,
foreach
不会有帮助。这段代码只是一个例子,让OP知道如何做。那么,为什么不每个方法检查前面的成功,例如
validPassword()
方法检查
emptyFields()&&strlen(…)>N
emptyFields()
检查
其他依赖条件()&&empty(…)
,然后在
寄存器()中
只调用了一个
isValid()
方法,该方法调用链中的最后一个方法?我将使用带有键的数组->发布字段、值->必要的消息,然后在数组中迭代,如果$\u post[$key]为空->$\u会话['msg']=$value。如果$\u post[$key]为空->$\u SESSION['msg']=$value,我将使用带有键的数组->发布字段,值->必要的消息,然后在数组中迭代。而不是每个字段的
if
,并返回。