php弱比较
在 PHP 中,弱比较(Weak Comparison)指的是在比较两个值时,PHP 可能会进行类型转换以使比较结果为 true
或 false
。弱比较通常涉及非严格的等于(==
)和不等于(!=
)操作符,而这些操作符会在比较之前进行隐式类型转换。
弱比较的基本概念
弱比较是 PHP 的一个特性,当两个不同类型的值进行比较时,PHP 会自动将它们转换为相同的类型,然后再进行比较。这个过程被称为 类型转换 或 类型强制。
弱比较的操作符
==
:等于!=
:不等于===
:严格等于!==
:严格不等于
在使用 ==
和 !=
时,PHP 会进行弱比较,也就是在比较之前自动转换数据类型;而 ===
和 !==
是严格比较,它们不进行类型转换,只有当值和类型都匹配时才会返回 true
。
示例和说明
1. 等于(==
)
在进行弱比较时,PHP 会尝试将两个不同类型的值转换为相同的类型,然后进行比较。
字符串和数字比较:
1
2
3<?php
var_dump("123" == 123); // bool(true)
?>这里
"123"
被转换为整数123
,因此比较结果为true
。布尔值和数字比较:
1
2
3
4<?php
var_dump(false == 0); // bool(true)
var_dump(true == 1); // bool(true)
?>false
被转换为0
,true
被转换为1
,因此都为true
。空值和其他值比较:
1
2
3
4<?php
var_dump(null == 0); // bool(true)
var_dump(null == ""); // bool(true)
?>null
和0
以及null
和空字符串""
都被认为是相等的。
2. 不等于(!=
)
类似于 ==
,PHP 在使用 !=
时也会进行类型转换。
字符串和数字比较:
1
2
3php复制代码<?php
var_dump("123" != 123); // bool(false)
?>因为
"123"
和123
被认为是相等的,所以结果是false
。布尔值和数字比较:
1
2
3
4<?php
var_dump(false != 0); // bool(false)
var_dump(true != 1); // bool(false)
?>false
和0
,true
和1
被认为是不等的结果为false
。
3. 严格比较(===
和 !==
)
严格比较不会进行类型转换,只有当两个值的类型和值都完全相同时才会返回 true
。
字符串和数字比较:
1
2
3<?php
var_dump("123" === 123); // bool(false)
?>"123"
是字符串类型,123
是整数类型,它们的类型不同,因此比较结果为false
。布尔值和数字比较:
1
2
3
4<?php
var_dump(false === 0); // bool(false)
var_dump(true === 1); // bool(false)
?>false
是布尔值,0
是整数;true
是布尔值,1
是整数,类型不同,因此比较结果为false
。
4. 空值比较
null
和其他值:1
2
3
4<?php
var_dump(null === 0); // bool(false)
var_dump(null === ""); // bool(false)
?>null
不等于任何非null
值,包括0
和空字符串""
,因此结果为false
。
可能出现的陷阱
隐式类型转换可能导致意外行为:
1
2
3
4
5
6<?php
$a = 0;
$b = "0";
var_dump($a == $b); // bool(true)
var_dump($a === $b); // bool(false)
?>在这个例子中,
$a
和$b
的值被认为是相等的(true
),但它们的类型不同,因此严格比较结果为false
。null
和非null
的值比较:1
2
3
4
5
6<?php
$a = null;
$b = false;
var_dump($a == $b); // bool(true)
var_dump($a === $b); // bool(false)
?>null
和false
被认为是相等的(在弱比较中),但在严格比较中它们不相等。
弱比较绕过示例
字符串与数字比较
弱比较允许字符串和数字进行比较,通过利用 PHP 的类型转换,可以绕过一些简单的验证。
1
2
3
4
5
6
7
8
9
10<?php
$userInput = "123";
$storedValue = 123;
if ($userInput == $storedValue) {
echo "Match found!";
} else {
echo "No match.";
}
?>在这个例子中,
"123"
和123
被认为是相等的,因为 PHP 会将"123"
转换为123
进行比较。布尔值与数字比较
false
被转换为0
,true
被转换为1
。可以利用这种特性绕过一些布尔值检查。1
2
3
4
5
6<?php
$input = false;
if ($input == 0) {
echo "False is equal to zero.";
}
?>在这里,
false
被转换为0
,因此条件成立。null
与其他值比较null
被认为与0
和空字符串""
相等。1
2
3
4
5
6<?php
$input = null;
if ($input == 0) {
echo "Null is considered equal to zero.";
}
?>这里,
null
与0
被认为是相等的,所以条件成立。数组与布尔值比较
空数组和非空数组在弱比较中与布尔值
false
和true
进行比较。1
2
3
4
5
6php复制代码<?php
$arr = [];
if ($arr == false) {
echo "Empty array is equal to false.";
}
?>在这个例子中,空数组
[]
被认为与false
相等。
例题:
[SWPUCTF 2021 新生赛]easy_md5
分析:
如果用get方法传入的name
的值不等于用post方法传入的password
的值,但它们的md5值相等就可以得到flag
我们通过传入这样的name[]=1
和password[]=2
,因为数组不能转换为md5所以都是null
若遇到===
这样的强类型比较,仍然有效,或者还可以使用软件fastcoll进行md5碰撞,生成两个字符串使得他们的md5值相同