似乎PHP的===运算符区分大小写。因此,有理由使用strcmp()吗?

执行以下操作是否安全?

if ($password === $password2) { ... }


评论

区分大小写与strcmp有什么关系?

@KennyTM:strcmp区分大小写。在某些语言中,例如VB,字符串比较可能不是,因此将返回不同的结果。但是,在PHP中不是这种情况。

@jie:您可能想使用===而不是==,因为'0XAB'=='0xab'是真实的。

使用===代替==很重要,因为将任何字符串与==比较为0都会返回true,这显然是false ...

@Kenny也是'0xAB'=='171'

#1 楼

之所以使用它,是因为如果str1小于str2,则strcmp


返回<0。 >如果str1大于str2,则为0,如果相等,则为0。


===仅返回truefalse,它不会告诉您哪个是“更大的”字符串。 br />

评论


在我当前的情况下,我不需要知道哪个字符串更大:)

–孟洁
2010年7月26日在9:11

匹配字符串的strcmp花费了0.207852秒匹配字符串的strcmp花费了0.215276秒===匹配字符串的时间花费了0.067122秒===匹配字符串的时间花费了0.057305秒snipplr.com/view/758

–user503853
13年4月22日在17:00

strcmp的其他用法显示排序。要更清楚地了解排序。如果string1在string2之前排序,则strcmp()返回<0;如果string2在string1之前排序,则返回> 0;如果它们相同,则返回0。例如$ string_first =“ aabo”; $ string_second =“ aaao”; echo $ n = strcmp($ string_first,$ string_second);将返回大于零,因为aaao正在aabo之前排序。

– HTML Man
13年8月16日在18:00

为什么这个答案获得最多的好评?我之所以投票,是因为尽管这是该问题应有的答案,但不是“正确的”答案。正确的答案应该是“使用===”,就像很多人在其他答案中已经说过的那样。

–onurgüngör
13年8月8日在8:14

@onurgüngör实际上,这确实回答了op的问题,那就是有没有理由使用strcmp()吗?而Postfuturist的回答却没有。哦,该死……似乎没有一个答案可以立即使用strcmp(),===的性能以及==对字符串比较的可靠可靠性来一次编译...因此我在列表中添加了我的答案。

– Balmipour
17年8月31日在17:19

#2 楼

绝对不要使用==进行字符串比较。 ===可以。

$something = 0;
echo ('password123' == $something) ? 'true' : 'false';


只需运行上面的代码,您就会明白为什么。

$something = 0;
echo ('password123' === $something) ? 'true' : 'false';


现在,好一点了。

评论


==不仅是不同类型的问题。即使两面都是线,有时也会产生意想不到的结果。尝试'1e3'=='1000'

–锑
2012年6月21日在1:54

0 =='password123'如何?

–安迪·洛贝尔(Andy Lobel)
2012年8月10日在2:41

@AndyLobel PHP使用奇数宽松比较规则将'password123'强制转换为数字,因为另一个操作数为数字,该字符串(与大多数情况一样)强制转换为数字0,PHP返回true进行比较。

–后未来主义者
2012年8月10日在5:15

快速var_dump((int)'password123');帮助我完全理解了为什么会发生这种情况... **尴尬** ...我真的很喜欢===运算符

–卡尔顿
2012年11月8日11:49

这是因为如果两个操作数之一都可转换为数字,则php会将两个操作数都转换为数字,并且,如果将非数字字符串转换为数字,则其值将为零,结果等于零,这是因为使用'=='因此,使用简单的'=='进行比较的结果可能会令人讨厌

– Luca C.
2014年8月1日在6:29

#3 楼

不要在PHP中使用==。它不会达到您的期望。即使将字符串与字符串进行比较,PHP也会将它们隐式转换为浮点数,并在它们显示为数字时进行数字比较。

例如'1e3' == '1000'返回true。您应该改用===

评论


@Roman是的,但是许多PHP程序员不知道他们必须这样做。因此,警告。

–锑
2013年1月25日4:36

@锑那么为什么不告诉他们他们应该怎么做呢?

– Tim
18年3月8日在16:19

#4 楼

嗯..根据此php bug报告,您甚至可以得到0wned。

<?php 
    $pass = isset($_GET['pass']) ? $_GET['pass'] : '';
    // Query /?pass[]= will authorize user
    //strcmp and strcasecmp both are prone to this hack
    if ( strcasecmp( $pass, '123456' ) == 0 ){
      echo 'You successfully logged in.';
    }
 ?>


它会警告您,但仍会绕过比较。
您应该按照@postfuturist的建议进行===

评论


哇+1。从链接中引用:“已为函数接收错误类型的参数以返回null的既定行为”。考虑到手册只是这样说,这是令人惊讶的:“如果str1小于str2,则返回<0;如果str1大于str2,则返回0;如果它们相等,则返回0”。没有提到空值,但在诸如substr手册页之类的页面上却提到了它。叹

–格里
13年7月4日在17:32

但是,当form方法是post ...时,会发生同样的事情吗?

– 3lokh
2014年2月28日在18:44

@NikhilGeorge确实如此,这里要讨论的函数是strcmp。与哪些输入进行比较并不重要。

– Ajith
14-10-11在19:52

虽然错误报告说可以返回null,但这是不正确的。从PHP 4.3到PHP 7.3的所有官方PHP版本都不会从这些函数返回null。我怀疑它可能是Alpha或Beta版本,并且无论关闭的错误是无效的,它都已修复。有关详细信息,请参见3v4l.org/Zq8tM,这表明它确实会影响HHVM 3.11-3.19。

– Timo Tijhof
18年6月26日在13:46



#5 楼

始终记住,比较字符串时,应使用===运算符(严格比较)而不是==运算符(宽松比较)。

评论


实际上,我认为可以肯定地说,在比较任何内容时都应使用===。

–rink.attendant.6
2015年6月9日在22:37

#6 楼


总结所有答案:



==对于字符串比较是个坏主意。
在很多情况下,它会使您“惊讶”。不要相信它。
===很好,并且将为您提供最佳性能。
如果需要确定哪个字符串“更大”,通常应用于排序操作,则应使用strcmp()


#7 楼

使用==可能很危险。

请注意,如果两者不同,它将把变量强制转换为另一种数据类型。

示例:


echo (1 == '1') ? 'true' : 'false';
echo (1 == true) ? 'true' : 'false';

如您所见,这两个来自不同类型,但结果是true,这可能不是您的代码所期望的。

但是,建议使用===,因为测试表明它比strcmp()快一点,并且它的大小写不敏感的替代形式strcasecmp()

快速谷歌搜索可以使速度比较:http://snipplr.com / view / 758 /

评论


有时,即使它们已经具有相同的类型,也将它们转换为其他类型。

–锑
13年4月25日在5:24

即使比较两个表示整数的字符串,例如“ 012” ==“ 12” php,两个字符串的类型也更改为整数12 == 12,然后返回true。

– GoTo
2014年9月23日在18:09

#8 楼

strcmp()===都区分大小写,但===速度更快

示例代码:http://snipplr.com/view/758/

#9 楼

strcmp将根据其运行的环境(Linux / Windows)返回不同的值!

原因是它有一个错误,因为错误报告说https://bugs.php.net/ bug.php?id = 53999

请谨慎处理!谢谢。

评论


但是,如果字符串相等,它将始终返回0。 +1表示注意除0以外的任何其他值。

–法尔肯教授
13年3月26日在10:05



#10 楼

如果您希望按字典顺序对字符串进行排序/比较,可以使用strcmp()。如果您只想检查是否相等,那么==就可以了。

评论


就像在usort中一样。实际上,它几乎是用于排序的。

–查尔斯
10年7月26日在8:46



@查尔斯谢谢。维基百科使我眼神呆滞。

–cbednarski
2010年7月26日在8:51

要更清楚地了解排序。如果string1在string2之前排序,则strcmp()返回<0;如果string2在string1之前排序,则返回> 0;如果它们相同,则返回0。例如$ string_first =“ aabo”; $ string_second =“ aaao”; echo $ n = strcmp($ string_first,$ string_second);将返回大于零,因为aaao正在aabo之前排序。

– HTML Man
13年8月16日在17:58

@postfuturist我确定这是一个错字,它们的意思是===。

–灰
16-3-29在16:17

#11 楼

此外,该功能还有助于分类。要更清楚地了解排序。如果string1在string2之前排序,则strcmp()返回小于0;如果string2在string1之前排序,则strcmp()返回0;如果它们相同,则返回0。例如

$first_string = "aabo";
$second_string = "aaao";
echo $n = strcmp($first_string,$second_string);


该函数将返回大于零的值,因为aaao在aabo之前进行排序。

#12 楼

PHP不使用字母排序,而使用字符的ASCII值进行比较。小写字母的ASCII值比大写字母高。最好使用标识运算符===进行这种比较。 strcmp()是执行二进制安全字符串比较的函数。它使用两个字符串作为参数,如果str1小于str2,则返回<0;否则,返回0。如果str1大于str2,则> 0;如果相等,则> 0。还有一个名为strcasecmp()的不区分大小写的版本,该版本首先将字符串转换为小写字母,然后对其进行比较。

#13 楼

在比较其中一个输入由用户控制的密码或密码散列时,if ($password === $password2) { ... }是不安全的事情。
在这种情况下,它会创建一个计时预告片,允许攻击者从执行时间差中得出实际的密码哈希。 br />请改用if (hash_equals($password, $password2)) { ... },因为hash_equals执行“定时攻击安全字符串比较”。