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

时间:2013-12-05 16:50:35

标签: php if-statement

我对为什么这不起作用感到困惑:

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;
}

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

  • 如果商家信息存在并且是经过批准的商家信息,请将其显示给用户
  • 如果商家信息存在但未获批准,请不要向用户显示
  • 如果商家信息存在,但未获批准,但已登录的用户是管理员或创建该商家的人员,请将其显示

所以上市将显示这些资格:

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

对此的任何帮助都很棒......我无法弄明白=(

3 个答案:

答案 0 :(得分:0)

当事情变得混乱时,最好将事情弄清楚,并使用我最喜欢的技巧来驱使一些数学家疯狂:使用不必要的parens和换行符!

现在,您的逻辑AND和OR根本无法正常工作......实际上,如果不重新访问某些语言规范,很难知道会发生什么。但这就像不得不依赖于数学中正确的操作列表 - 我们是程序员,所以忘记爵士乐 - 更多的parens和白色空间!让我们摆脱不合格的“不”(!)用法,使其更加明确,因为这已经让人感到困惑。

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循环中,很难找到究竟发生了什么。使用分支逻辑,您可以更容易地逐行“观察”逻辑如何根据不同的输入进行播放。

如果我可以提供我的个人编码理念之一:

  

首先,这样做很难看。   然后,当它工作时,让它漂亮。   但不要忘记 - 有时丑陋只会掩盖真正的美丽。

一旦有些东西起作用,它就变得更容易了。但是如果某些东西很漂亮且不起作用,它总会变得难看。

答案 1 :(得分:0)

您已经将问题分解为特定的条件情况,因此不要使用难以跟踪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.
}

答案 2 :(得分:0)

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()
                                 ) );

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