几天前,我开始为我的项目实现简单的安全功能,以防止用户查看其他用户添加到数据库的客户。当我这样做时,我感到困惑,因为我意识到标准的逻辑运算符以奇怪的方式工作。
这是我最初写的代码:
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均为真,则为真”
它开始正常工作,这意味着你可能不是客户的所有者,但如果你是管理员,你将被允许访问而不是注销。
此时我害怕我向后理解,有人可以解释为什么它看起来不符合逻辑吗?它究竟是如何工作的?提前谢谢。
答案 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 = 5
和access_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 = 3
和access_level($session_user_id) level = 2
。这意味着$current_user_id != $session_user_id
false ,access_level($session_user_id) != 3
true 。同样,这意味着||
true ,因此if
成功并且用户已退出。