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值相同