【问题标题】:Not operator with multiple or operator非运算符与多个 or 运算符
【发布时间】:2013-11-28 06:15:08
【问题描述】:

我对下面的代码感到困惑:

不工作的拳头代码:

if ($_SESSION['userType'] != 'A' || $_SESSION['userType'] != 'S')
{
    redirect('dashboard.php');
}

正在运行的第二个代码:

if (!($_SESSION['userType'] == 'A' || $_SESSION['userType'] == 'S'))
{
    redirect('dashboard.php');
}

这两个代码有什么区别?

【问题讨论】:

  • 在第一部分,两个条件都返回 false,在第二部分,两个条件都返回 false,!(false) 等于 true。
  • 他们不再在学校教De Morgan's Law了吗?

标签: php logic


【解决方案1】:

我知道你的问题已经有六个答案,但没有一个使用简单的英语,所以我自己也会尝试。

让我们一步一步看这段代码,把它分成更小的部分,并准确地解释每一步。


无效的代码

首先你有这一行:

if ($_SESSION['userType'] != 'A' || $_SESSION['userType'] != 'S')

与其查看完整的 if 子句,不如将其分为两部分:

  1. if ($_SESSION['userType'] != 'A')
  2. if ($_SESSION['userType'] != 'S')

只要$_SESSION['userType']A 以外的任何值,第一部分就会触发。

第二部分将在$_SESSION['userType'] 是除S 之外的任何值时触发。

现在,您已经使用“或”运算符将它们连接在一起,因此只要其中一个为真即可触发 if 子句。让我们看看当我们尝试时会发生什么。

  1. 我们将 $_SESSION['userType'] 设置为 'B' 并进入 if 子句。发生的第一件事是 PHP 查看第一部分 if ($_SESSION['userType'] != 'A'),并找到 'B' != 'A'。它不需要进入第二部分,因为它已经发现if语句的一部分为真,因此它决定完整的if语句也必须为真。

  2. 我们将 $_SESSION['userType'] 设置为 'A' 并进入 if 子句。发生的第一件事是 PHP 查看第一部分if ($_SESSION['userType'] != 'A'),发现'A' == 'A',所以第一部分为假。然后它继续到第二部分,即if ($_SESSION['userType'] != 'S'),并找到'A' != 'S'。由于这意味着 if 语句的一部分为真,它再次决定完整的 if 语句也必须为真。

现在请注意这意味着什么。即使您将'A' 发送到 if 子句,由于第二部分,它仍然会触发。如果您要发送'S',它将因为第一部分而触发。因此,基本上,无论$_SESSION['userType'] 设置为什么,都会触发完整的第一个 if 语句。这是一个重言式 - 它总是正确的。


有效的代码

这是完整的 if 语句:

if (!($_SESSION['userType'] == 'A' || $_SESSION['userType'] == 'S'))

我们暂时先忽略!,把它分成or操作符的两部分。

  1. if ($_SESSION['userType'] == 'A')
  2. if ($_SESSION['userType'] == 'S')

请注意,这与您所拥有的无效代码的逻辑相反。第一行表示“只接受'A'”,第二行表示“只接受'S'”。因此,此代码在您给它'A''S' 时才会触发。

现在,如果你像以前一样在整个内容前面加上 ! 会发生什么?

! 运算符只是简单地反转它前面的内容。因此,这将含义从“AS”更改为“既不是 A 也不是 S”。


总结

您的第一个示例归结为“任何价值”。

您的第二个示例归结为“任何值,但不是A,也不是S”。

如果您想了解更多基本逻辑,我建议您查看De Morgan's laws,正如您在上面的评论中所链接的那样。这将使您了解andor 如何组合在一起。

【讨论】:

    【解决方案2】:

    不……完全。

    如果我没记错布尔逻辑,错误在于操作顺序。

    if ($_SESSION['userType'] != 'A' || $_SESSION['userType'] != 'S') {
    

    如果 userType 等于 A,这将不起作用...因为第一个操作是检查它是否不等于 A 并且 OR 是从左到右...所以如果第一个不正确,则整个语句是假的。

    您的第二种方法转化为:

    if (!($_SESSION['userType'] == 'A' || $_SESSION['userType'] == 'S'))
    {
        redirect('dashboard.php');
    }
    

    IF NOT userType 等于 A 或 userType 等于 S,这就是为什么它可以按您的意愿工作。

    试试

    if ($_SESSION['userType'] != 'A' && $_SESSION['userType'] != 'S')) {
    

    这意味着如果 userType 不是 A 并且 userType 不是 S

    我认为这将为您提供您可能正在寻找的东西。 IE 仅当 userType 既不是 A 也不是 S 时才执行循环中的内容。

    【讨论】:

    • 第二个短语中没有&&
    • 对不起...迟到了 :) 第二句话是针对发布的第一个答案,而不是他自己的代表。更新以反映这一点并包括他的第二个短语。
    • 别担心别人的答案。只需直接回答问题即可。
    【解决方案3】:
    if ($_SESSION['userType'] != 'A' || $_SESSION['userType'] != 'S') {
    

    或多或少等同于

    if (!($_SESSION['userType'] == 'A' && $_SESSION['userType'] == 'S')) {
    

    【讨论】:

    • 这就是区别。
    • 哦,你是说||&&?你本来可以更清楚的。
    【解决方案4】:

    第一个不工作的代码

    if ($_SESSION['userType'] != 'A' || $_SESSION['userType'] != 'S')
    {
        redirect('dashboard.php');
    }
    

    让我们简单化如下:

    if (true || true) //the condition will be true or vice versa
    {
        redirect('dashboard.php');
    }
    

    正在运行的第二个代码:

    if (!($_SESSION['userType'] == 'A' || $_SESSION['userType'] == 'S'))
    {
        redirect('dashboard.php');
    }
    

    和简化版:

    if (!(true || true)) same as if (!(true)) //i.e. false or vice versa
    {
        redirect('dashboard.php');
    }
    

    所以基本上一个是真的,另一个是假的,反之亦然,这就是他们表现不同的原因。

    【讨论】:

    • 你并没有真正解释什么。
    • @RobertHarvey 我认为上面的例子清楚地解释了一切。再看看
    • 感谢您的参与。
    • @RobertHarvey 这是什么意思?
    • 这对您来说非常有意义,因为您编写了它。并不意味着你在解释它。
    猜你喜欢
    • 1970-01-01
    • 2015-07-08
    • 2014-02-24
    • 2014-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 2016-05-31
    相关资源
    最近更新 更多