PHP – вложенные выражения IF

Мне интересно, когда плохой идеей использовать несколько вложенных операторов IF.

например:

function change_password($email, $password, $new_password, $confirm_new_password) { if($email && $password && $new_password && $confirm_new_password) { if($new_password == $confirm_new_password) { if(login($email, $password)) { if(set_password($email, $new_password)) { return TRUE; } } } } } 

Эта функция используется следующим образом:

 if(!change_password($email, $password, $new_password, $confirm_new_password) { echo 'The form was not filled in correctly!'; exit; } 

Я называю все мои функции такими, и мне интересно, что-то не так с моим стилем кодирования. У меня возникают сомнения, потому что, если я последую этому дизайну, это означает, что каждая отдельная функция, которую я пишу, будет только с вложенными IF, проверяя, есть ли ошибки на каждом этапе. Это то, что делают другие люди?

Я не вижу много других сценариев, написанных так: вложенные IF формируют треугольную форму и имеют только желаемый результат в самой середине. Если середина не достигнута, то что-то прищурилось.

Является ли это хорошей функциональной структурой?

Вложение слишком глубоко – это, как правило, плохая идея – это логика спагетти и трудно следовать. Поскольку каждый из шагов проверки зависит от того, что предыдущий этап преуспел, не гнездитесь вообще – просто выйдите из строя, когда сбой этапа:

 function change_password(blah blah blah) { if (!$condition1) { return false; } if (!$condition2) { return false; } etc.... // got here, must have succeeded return true; } 

Это явно указывает на то, что логическая последовательность.

Я думаю, что он определенно хорошо читаем и его легко понять по сравнению с использованием только одного утверждения if

 if (blah and blah and blah and blah and blah and blah and blah) {} 

Однако я бы предпочел сделать это так – слишком много отступлений может вызвать раздражение:

 function change_password($email, $password, $new_password, $confirm_new_password) { if (!$email || !$password || !$new_password || !$confirm_new_password) return false; if ($new_password != $confirm_new_password) return false; if (!login($email, $password)) return false; if (!set_password($email, $new_password)) return false; return true; } 

Это может быть полезно для их гнездования, потому что, изменяя порядок, вы можете избежать дополнительных сравнений. То, что вы сейчас делаете, выглядит хорошо, однако ваша функция будет менее эффективной, если вы вместо этого напишите ее как:

 function change_password($email, $password, $new_password, $confirm_new_password) { if($new_password == $confirm_new_password && $email && $password && $new_password && $confirm_new_password) { if(login($email, $password)) { if(set_password($email, $new_password)) { return TRUE; } } } } 

Если $ new_password == $ confirm_new_password истинно, но $ email пуст, вы сделаете дополнительное сравнение.

Как говорили другие, есть и другие способы обойти это, не вложив все, что будет функционально эквивалентным.