几天前,我开始在我的项目中实现简单的安全功能,以防止用户查看其他用户添加到数据库中的客户。当我这样做时,我感到困惑,因为我意识到标准逻辑运算符的工作方式很奇怪。
这是我最初编写的代码:
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 = 5
和access_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 = 3
和access_level($session_user_id) level = 2
。这意味着$current_user_id != $session_user_id
是假的,access_level($session_user_id) != 3
是真的。同样,这意味着||
为真,因此if
成功并且用户注销。