PHP 逻辑运算符 “&&” 和 “||“,同时构建简单的安全功能


PHP logical operators "&&" and "||" while building simple security function

几天前,我开始在我的项目中实现简单的安全功能,以防止用户查看其他用户添加到数据库中的客户。当我这样做时,我感到困惑,因为我意识到标准逻辑运算符的工作方式很奇怪。

这是我最初编写的代码:

if($current_user_id != $session_user_id || access_level($session_user_id) != 3) {
    header('Location: logout.php');
    exit();
}

这意味着,如果您尝试查看的存储客户不属于您或您的访问级别不是 3(管理员(,您将被注销。它应该按照这个工作:

http://www.w3schools.com/php/php_operators.asp

他们说||的意思是"如果条件 1 或条件 2 为真,则为 true",因此,如果任何条件没有失败,它应该允许访问。当然不是,脚本的行为只是写入第一个条件,这意味着如果您是管理员,那么您的访问级别为 3,并且您正在查看的不是您的客户 - 您仍然会被注销。

这是开始工作的微小修改:

if($current_user_id != $session_user_id && access_level($session_user_id) != 3) {
    header('Location: logout.php');
    exit();
}

切换到 && 后,这意味着"如果条件 1 和条件 2 都为真,则为 true"它开始正常工作,这意味着您可能不是客户的所有者,但如果您是管理员,您将被允许访问而不是注销。

在这一点上,恐怕我倒着理解了,有人可以解释为什么它似乎不合逻辑吗?它究竟是如何工作的?提前谢谢你。

您的逻辑是,在以下情况下,应允许用户访问:

  • 他们是所有者,或
  • 是管理员

通过此逻辑,您可以构造以下语句:

if( $user == $owner || access_level($user) == 3) {
    // allow access
}

但是您使用的是否定位置,即,如果他们既不是所有者也不是管理员,则不允许访问。这意味着您必须否定整个if语句。

查看||&&的真值表:

A B A||B A&&B
0 0  0    0
0 1  1    0
1 0  1    0
1 1  1    1

由此可以看出,为了得到A||B的反面,我们需要!A && !B

A B !A !B A||B !A&&!B
0 0 1  1   0     1
0 1 1  0   1     0
1 0 0  1   1     0
1 1 0  0   1     0

因此,要编写此内容,请执行以下操作:

if( !($user == $owner) && !(access_level($user) == 3) ) { /* deny access */ }

当然可以写成:

if( $user != $owner && access_level($user) != 3) { /* deny access */ }

这个:

这意味着,如果您尝试查看的存储客户不属于您或您的访问级别不是 3(管理员(,您将被注销。

不需要这个:

如果任何条件没有失败,它应该允许访问

参见德摩根定律。

第一个语句基本上是(!a || !b) .否定它(即!(!a || !b)(实际上切换到运算符成为:(a && b)

因此,你的第二条声明应为:

如果这两个条件都没有失败,则应允许用户访问[任何]

好吧,你来了:

$a && $b表示如果将$a$b设置为 true,则条件为 true。

$a || $b表示必须将$a$b(或两者(设置为 true。

!$a && $b意味着$a必须false$b必须true

!$a || $b意味着$a必须false$b必须true

$a != $b意味着$a必须不等于$b

$a == $b意味着$a必须等于$b

$a > $b意味着$a必须大于$b

$a < $b意味着$a必须小于$b

等等...

他们是比较运算符,看看吧!

在您的第一个示例中,您使用 OR 运算符,但希望为以下代码匹配 2 个条件,但可以匹配一个或另一个。

例如,如果用户不是用户级别 3,则无论是否 $current_user_id != $session_user_id签证,反之亦然。

使用 AND 运算符意味着在注销之前必须同时匹配这两个条件。

假设$current_user_id = 3$session_user_id = 5access_level($session_user_id) level = 3。这意味着$current_user_id != $session_user_id真的access_level($session_user_id) != 3的。 如果任一条件为,则||为 true,因此if成功并且用户注销。

或者假设$current_user_id = 3$session_user_id = 3access_level($session_user_id) level = 2。这意味着$current_user_id != $session_user_id的,access_level($session_user_id) != 3是真的。同样,这意味着||为真,因此if成功并且用户注销。