“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查询的结果,以避免将用户id
0
null
或false与
=
进行比较。例如,如果您将MySQL direct的结果分配给一个变量,而不检查它是否失败,那么它可能会导致该变量为false或null,并导致一个真正的匹配。谢谢,伙计,解释得很好!