长篇IF声明.混淆在OR和and之间



我很困惑为什么这不起作用:

if( ( ! $listing_info && $listing_info['status'] !== $this->get_approved()) || $listing_info['user_id'] !== $this->auth->get_user_id() || $listing_info['user_group'] !== $this->get_admin()) {
    return false;
}

好的,所以我的dilemna是这些要求。用户正在查看列表。

  • 如果该列表存在并且是已批准的列表,请将其显示给用户
  • 如果列表存在,但未获得批准,则不向用户显示
  • 如果该列表存在,但未获得批准,但登录的用户是管理员或创建该列表的人,则显示该列表

因此,上市将显示这些资格:

  • 列表已存在并已批准
  • 列表的所有者可以查看列表,而不管其状态如何
  • 管理员可以查看所有列表,无论其状态如何

这方面的任何帮助都将是美妙的。。。我想不通=(

当事情变得令人困惑时,最好将事情分解,并使用我最喜欢的让一些数学家疯狂的技巧:使用不必要的括号和换行符!

现在,你的逻辑AND和OR根本不会像你预期的那样工作。。。事实上,如果不重新审视一些语言规范,很难知道会发生什么。但这就像必须依赖数学中列出的正确操作顺序——我们是程序员,所以忘了爵士乐——更多的parens和white space!让我们去掉不合格的"not"(!)用法,使其更加明确,因为这已经有点令人困惑了。

if(
    $listing_info != true && (
        ( $listing_info['status'] !== $this->get_approved() ) || 
        ( $listing_info['user_id'] !== $this->auth->get_user_id() ) ||
        ( $listing_info['user_group'] !== $this->get_admin() ) )
    ) 
{
    return false;
}

所以,这里的逻辑要清晰得多。。。可能是错的。

首先,parens现在明确表示,这是一个有两个条件的事情——列表信息本身一定不是真的(嗯?我觉得这是打字错误),下一个条件必须返回true。要到达这个位置,至少3个OR条件中的某些内容必须返回为true。

另一个清晰的问题是,一切都是负面的,这会让人头疼。默认情况下,人类不会这样想,所以很容易混淆。通常最好写:

if ($control == false)

比写入:

if ($control != true)

因为从认知角度来说,第一个需要更少的心理计算,即使计算机不太关心你选择哪一个。在简单的情况下,这并不是什么大不了的事情,但当你开始构建这样的分支逻辑并嵌套and和OR条件时,它会很快变得令人困惑。我保存PHP风格$仅针对单个逻辑的条件。

如果你不能,因为它没有意义,就像你的OR语句一样,你只需要理解它会更难思考,并使用其他技巧让它更容易一目了然。

现在,需要明确的是,如果你简单地将其分解为公认的丑陋的分支if语句,你会发现发现发现逻辑问题要容易得多,并且可以更快地修复错误。如果没有别的,调试器自然会一行接一行地进行,并且将所有内容都塞进一个If循环中,很难找出到底发生了什么。使用分支逻辑,您可以更容易地逐行"观察"逻辑如何根据不同的输入进行处理。

如果我可以提供我个人的编码哲学之一:

首先,做得丑陋。然后,当它起作用时,让它变得漂亮。但别忘了,有时候丑陋只会掩盖真正的美丽。

一旦某件事成功了,就更容易让它变得漂亮。但是,如果某个东西很漂亮,不起作用,它总是会变得丑陋。

您已经将问题分解为特定的条件案例,因此,与其使用难以跟踪的if/then概念,不如将案例建模为函数,并获得一些易于阅读、功能正确且重要的:易于调试的代码作为回报:

function renderListing($isadmin) {
  // render the listing, if $isadmin is true, with some admin controls
}
function showListing() {
  if($user->isAdmin()) {
    renderListing(true);
    // due to the additional requirements you already know, this
    // if block and the next one that uses renderListing cannot
    // be replaced with a single renderListing($user->isAdmin())
  }
  else if($listing->isApproved()) {
    renderListing(false);
  }
  //else do nothing, or render a placeholder, or an empty something, etc.
}
return ( isset($listing_info) && (
           $listing_info['status'] == $this->get_approved() ||
           $listing_info['status'] != $this->get_approved() &&
             ( $listing_info['user_id'] == $this->auth->get_user_id() ||
               $listing_info['user_group'] == $this->get_admin() )
                                 ) );

也许能胜任这份工作。可以通过删除多余的审批检查来简化它(只有在未批准的情况下,它才会出现在id/组检查部分):

return ( isset($listing_info) && (
           $listing_info['status'] == $this->get_approved() ||
           $listing_info['user_id'] == $this->auth->get_user_id() ||
           $listing_info['user_group'] == $this->get_admin()
                                 ) );

我不知道你是否需要===/!===比较或只是===/!=。当然,如果这是有效的,应该对它进行彻底的评论来解释,否则到下周你就会忘记它是如何工作的。

最新更新