3

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

这是我最初编写的代码:

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 都为真,则为真”后,它开始正常工作,这意味着您可能不是客户的所有者,但如果您是管理员,您将被允许访问并且不会注销。

在这一点上,我恐怕我理解它倒退,有人可以解释为什么它看起来不合逻辑吗?它究竟是如何工作的?先感谢您。

4

5 回答 5

6

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

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

按照这个逻辑,你可以构造这个语句:

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 */ }
于 2013-09-02T22:31:03.913 回答
3

这个:

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

不包括这个:

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

参见德摩根定律

第一条语句本质上是(!a || !b). 否定那个 (ie, !(!a || !b)) 实际上会切换到 operator 成为: (a && b)

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

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

于 2013-09-02T22:34:35.453 回答
0

好吧,你在这里:

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

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

!$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

等等...

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

于 2013-09-02T22:26:57.863 回答
0

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

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

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

于 2013-09-02T22:33:20.630 回答
0

假设$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 ,则为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真的。同样,这意味着true,因此||成功并且用户已注销。if

于 2013-09-02T22:34:39.477 回答