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

时间:2013-09-02 22:21:07

标签: php

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

这是我最初写的代码:

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为真,则为真”,因此如果任何条件没有失败,则应允许访问。当然不是,脚本表现为只写入第一个条件,这意味着如果您是管理员,那么您的访问级别为3而您正在查看的不是您的客户 - 您仍然会被注销。

这是一个小修改,开始起作用:

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

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

此时我害怕我向后理解,有人可以解释为什么它看起来不符合逻辑吗?它究竟是如何工作的?提前谢谢。

5 个答案:

答案 0 :(得分:6)

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

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

通过这种逻辑,你可以构造这个陈述:

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

但你正在使用负面立场,即。如果他们不是所有者NOR管理员,则禁止访问。这意味着您必须否定整个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 */ }

答案 1 :(得分:3)

此:

  

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

不需要这个:

  

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

请参阅De Morgan's law

第一个陈述基本上是(!a || !b)。否定(即!(!a || !b))实际上切换到运算符变为:(a && b)

因此,您的第二个陈述应为:

  

如果条件

答案 2 :(得分:0)

嗯,你在这里:

$a && $b表示如果$a$b设置为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

依旧......

他们是Comparison Operators,请查看!

答案 3 :(得分:0)

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

E.G因此,如果用户不是用户级别3,则无论是否会注销 $current_user_id != $session_user_id或反之亦然。

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

答案 4 :(得分:0)

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

或者假设$current_user_id = 3$session_user_id = 3access_level($session_user_id) level = 2。这意味着$current_user_id != $session_user_id false access_level($session_user_id) != 3 true 。同样,这意味着|| true ,因此if成功并且用户已退出。