“PHP逻辑运算符”&&&引用;及||&引用;同时构建简单的安全功能
几天前,我开始在我的项目中实现简单的安全功能,以防止用户查看其他用户添加到数据库中的客户。当我这样做时,我感到困惑,因为我意识到标准逻辑运算符的工作方式很奇怪 这是我最初编写的代码:“PHP逻辑运算符”&&&引用;及||&引用;同时构建简单的安全功能,php,Php,几天前,我开始在我的项目中实现简单的安全功能,以防止用户查看其他用户添加到数据库中的客户。当我这样做时,我感到困惑,因为我意识到标准逻辑运算符的工作方式很奇怪 这是我最初编写的代码: if($current_user_id != $session_user_id || access_level($session_user_id) != 3) { header('Location: logout.php'); exit(); } 这意味着,如果您试图查看的存储客户不属于您,或者您
if($current_user_id != $session_user_id || access_level($session_user_id) != 3) {
header('Location: logout.php');
exit();
}
这意味着,如果您试图查看的存储客户不属于您,或者您的访问级别不是3(管理员),则您将注销。它应该根据这一点工作:
他们说,|
的意思是“如果条件1或条件2为真,则为真”,因此如果任何条件未失败,则应允许访问。当然不是,脚本的行为只是编写了第一个条件,这意味着如果您是管理员,那么您的访问级别是3,并且您正在查看的不是您的客户,那么您仍然将被注销
这是开始工作的小修改:
if($current_user_id != $session_user_id && access_level($session_user_id) != 3) {
header('Location: logout.php');
exit();
}
切换到&&
后,表示“如果条件1和条件2均为真,则为真”
它开始正常工作,这意味着您可能不是客户的所有者,但如果您是管理员,您将被允许访问,而不是注销
在这一点上,我恐怕我倒过来理解了,有人能解释一下为什么它看起来不符合逻辑吗?它到底是如何工作的?提前谢谢你。好了,给你:
$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
等等
是的,看看 您的逻辑是,在以下情况下,应允许用户访问:
- 他们是所有者,或者
- 他们是管理员
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 */ }
在第一个示例中,您使用OR运算符,但希望为以下代码匹配2个条件,但其中一个条件可以匹配 例如,如果用户不是3级用户,则无论是否
$current\u user\u id!=$会话用户id
或visa国际组织id
使用AND运算符意味着在注销之前必须匹配这两个条件。这:
这意味着,如果您试图查看的存储客户不属于您,或者您的访问级别不是3(管理员),则您将注销
这并不意味着:
如果任何条件没有失败,它应该允许访问
看
第一条语句本质上是(!a | |!b)
。否定它(即,!(!a | |!b)
)实际上会切换到操作符,变成:(a&&b)
因此,你的第二项声明应为:
如果两个条件都没有失败,则应允许用户访问[任何内容]
假设
$current\u user\u id=3
,$session\u user\u id=5
,以及访问级别($session\u user\u id)级别=3
。这意味着$current\u user\u id!=$session\u user\u id
为true,并且访问级别($session\u user\u id)!=3
为假<如果任一条件为true,则代码>|为true,因此如果成功且用户注销
或者假设$current\u user\u id=3
,$session\u user\u id=3
,以及访问级别($session\u user\u id)级别=2
。这意味着$current\u user\u id!=$会话用户id
为假,且访问级别($session用户id)!=3
为真。同样,这意味着|
是真的,因此如果
成功并且用户注销。最好的办法是尝试找出变量实际包含的内容。尝试执行var\u dump($current\u user\u id);变量转储($session\u user\u id);变量转储(访问级别($session\u user\u id))代码>并手动处理逻辑。检查:我希望您正确验证了MySQL查询的结果,以避免将用户id0
与null
或false与=
进行比较。例如,如果您将MySQL direct的结果分配给一个变量,而不检查它是否失败,那么它可能会导致该变量为false或null,并导致一个真正的匹配。谢谢,伙计,解释得很好!