构造条件逻辑的最佳方法是什么?

时间:2010-07-20 02:36:02

标签: php formatting conditional

我发现有许多不同的方法来构造条件逻辑。据我所知,只要我们设置错误来结束脚本(或者您可以想象相同的示例但在函数中返回),那么以下示例是相同的:

示例1

if($condition1) {
    trigger_error("The script is now terminated");
    }

if($condition2) {
    trigger_error("The script is now terminated");
    }

echo "If either condition was true, we won't see this printed";

示例2

if(!$condition1) {
    if(!$condition2) {
        echo "If either condition was true, we won't see this printed";
        }
    else {
        trigger_error("The script is now terminated");
        }
    }
else {
    trigger_error("The script is now terminated");
    }

示例3

if($condition1) {
    trigger_error("The script is now terminated");
    }
else {
    if($condition2) {
        trigger_error("The script is now terminated");
        }
    else {
        echo "If either condition was true, we won't see this printed";
        }
    }

示例4 - 改编自Fraser's Answer

function test($condition) { 
    if($condition) {
        trigger_error("The script is now terminated");
        }   
    }

test($condition1);

test($condition2);

echo "If either condition was true, we won't see this printed";

就个人而言,我倾向于编写代码,如例1所示。这是因为我觉得通过检查以这种方式结束脚本(或函数)的条件,我可以清楚地定义脚本执行和不执行的内容,即一切在条件执行之前和行之后的所有内容都没有。这意味着当我在第147行收到错误时,我立即知道发生了什么事情,帮助我更快地找到错误。此外,如果我突然意识到我需要在$ condition1之前测试$ condition2,我可以通过简单的复制粘贴进行更改。

我看到很多代码都像例2中那样编写,但对我来说,调试看起来要复杂得多。这是因为,当嵌套变得太大时,错误将在底部的某条远线处被触发,并与由大量嵌套代码引起它的条件分开。此外,改变条件序列可能会更加混乱。

你可以混合两种风格,例如在例3中,但这似乎使事情过于复杂,因为所有'其他'本质上是多余的。

我错过了什么吗?构建条件代码的最佳方法是什么?有比这些例子更好的方法吗? 是否存在一种风格可能优于另一种风格的具体情况?

编辑:示例4看起来非常有趣,并不是我考虑过的事情。您还可以传递错误消息作为第二个参数。

谢谢!

P.S。请记住,我可能需要在检查$ condition1和$ condition2之间执行一些任意步骤,以便任何替代方案都必须适应。否则,有一些更好的替代方案,例如if($ condition1 || $ condition2)。

10 个答案:

答案 0 :(得分:8)

我在示例1 阵营。根据经验,所需的压痕越少越好。

// Exit early if there are errors.
if ($n < 0) {
    die "bad n: $n";
}

// Handle trivial cases without fuss.
if ($n == 0) {
    return 0;
}

/* Now the meat of the function. */
$widget->frob($n);
foreach ($widget->blaxes as $blax) {
    checkFrobbingStatus($blax);
}
// ...And another 20 lines of code.

当您使用if / else并将成功和错误代码放在并行部分中时,您会看起来好像两个代码块相同。实际上,应该不再强调边缘情况和错误条件。通过故意有意地处理错误,然后将“重要”代码放在else子句中,我觉得这样可以在视觉上更清晰地显示重要代码。

“以下是所有先决条件。现在这里是好事。”

答案 1 :(得分:3)

就我个人而言,我讨厌嵌套的if-else语句,因此对我来说是#1。我会看到的另一个选项是以下内容。

function test($condition) { 
  if($condition) {
    trigger_error("The script is now terminated");
  }   
}

test($condition1);

//do stuff...

test($condition2);

//passed the tests
编辑:我认为它越多,功能性方法是迄今为止最好的方法,因为它不必编写不止一次测试条件的逻辑。它还允许更高的可读性,因为很明显你正在“测试”条件(只要你给函数一个有意义的名字)。此外,正如问题编辑中指出的那样,将其他参数传递给函数是微不足道的。即。

function test($c, $msg) { 
  if($c) {
    trigger_error($msg);
  }   
}

test($condition1, "condition1 error");
test($condition2, "condition2 error");

答案 2 :(得分:2)

到目前为止,#1是最清晰的。但是,如果某种程度上以前结束执行的事情被改变为做其他事情,那么它就会破裂。

最好与#1一起使用,但要确保用于“停止”的内容明确命名为 停止操作,以便10年内有人维护你代码不会通过更改它而意外破坏。

答案 3 :(得分:1)

我认为你的方法(例子1)在这种情况下是最有效和最有效的。但是,有时您不希望任何条件停止执行,而您只想在condition2为假时执行condition1。在这些情况下,elseelseif效果很好。

答案 4 :(得分:1)

我更喜欢这种风格,如果条件块中的任何一个被更改,它们就不会中断,因此它们不会退出执行。

if($condition1) {
    trigger_error("The script is now terminated");
}
if($condition2) {
    trigger_error("The script is now terminated");
}

if (!$condition1 && !$condition2) {
  echo "If either condition was true, we won't see this printed"; 
}

编辑:错过了PS,因此更新了代码以匹配完整的问题详情。

答案 5 :(得分:1)

我建议在任何可能出错的部分使用'try'子句,并在每次发生错误时使用'throw'错误说明“'(例如#1)。
这样,您可以在程序中使用错误报告代码一次(在'catch'子句中)并将代码拆分为函数将不会是一个麻烦的重写错误handlig。

答案 6 :(得分:1)

我普遍同意Amber,因为你的第一个选项似乎最清晰。这是我与自己斗争的事情 - 到目前为止,我偶然发现的唯一理由如下:

  • 阅读线性脚本时,第一种形式最为清晰,非常适合简单的脚本
  • 当您需要确保整洁/清理操作时,第二种形式是最清洁的

我提到第二个,因为这是一个棘手的问题。每个脚本可能是更大系统的一部分,实际上,您注入“保释”代码的脚本元素可能被多个地方调用。扔进一些OO,你就有了一个真正的潜在泡菜。

我可以推荐的最好的经验法则是,如果您的脚本是简单和线性的,或者您正在进行快速原型设计,那么您希望使用第一个表单并在此时终止执行。任何更复杂或“企业风格”都将受益于(至少)模块化重新设计,因此您可以隔离方法和调用堆栈 - 并可能封装OO构建。

现在有了一些更强大的调试和跟踪工具,它变得更加个性化而非必要性。您可能考虑的另一个选择是在每个纾困区之前(以及可能在之后)将信息放入评论中,这样可以明确在符合标准(或失败)时的替代方案。

修改

我会说Fraser's answer是封装最干净的。我唯一想补充的是你可以将对象或哈希数组传递给标准的“​​保释,我死”方法,这样你就可以修改函数可用的信息而不必一直更改参数列表(非常烦人......)。

那就是说 - 在生产系统中要小心,你可能需要在中间状态下清理资源。

答案 7 :(得分:0)

我也更喜欢#1。

另外,我真的很想在条件

期间分配变量

e.g。

if ( !$userName = $user->login() ) {
    die('could not log in');
}

echo "Welcome, $username";

我通常会发现在第一次编写代码时,我最终得到了一些杂乱的嵌套条件语句,所以通常在第二次传递期间我会回去清理一下,解除很多条件句我可以。

除了看起来更整洁之外,我发现在概念上更容易理解代码,而不必在心理上跟踪分支逻辑。

对于包含大量过程代码的无法删除的分支逻辑,我通常最终将它放在函数/类方法中 - 理想情况下,我可以在一个屏幕上看到正在发生的所有分支逻辑,但修改动作或逻辑不会破坏另一个。

答案 8 :(得分:0)

示例5

if($condition1 || $condition2)
{
    echo "If either condition was true, we won't see this printed";
}else
{
    trigger_error("The script is now terminated");
}

示例6

function allAreTrue()
{
    foreach(func_get_args() as $check)
    {
       if(!$check)
       {
           return false;
       }
    }
    return true;
}

if(allAreTrue(true,true,$condition1,$condition2,false))
{
   exit("Invalid Arguments");
}

//Continue 

答案 9 :(得分:-3)

构建条件逻辑的最佳方法是遵循逻辑本身。

如果你有依赖关系,比如说,第一个条件失败会让别人不必要是一回事。然后是returngoto,您选择的嵌套条件和例外。

如果你要做一个测试决定,请说

if (!isset($_GET['id'])) { 
  //listing part: 
} else { 
  // form displaying part: 
}  

它是elseelseifcase领域。

等。
首先确定你的程序逻辑,然后写出它的逻辑。

trigger_error()与条件无关。它是调试功能,而不是与程序逻辑相关的功能。