使用 '==' 与 'strcmp()' 进行字符串比较

Posted

技术标签:

【中文标题】使用 \'==\' 与 \'strcmp()\' 进行字符串比较【英文标题】:String comparison using '==' vs. 'strcmp()'使用 '==' 与 'strcmp()' 进行字符串比较 【发布时间】:2011-03-20 23:41:48 【问题描述】:

php=== 运算符似乎区分大小写。那么有理由使用strcmp()吗?

执行以下操作是否安全?

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

【问题讨论】:

大小写敏感与strcmp有什么关系? @KennyTM: strcmp 区分大小写。在某些语言中,如 VB,字符串比较可能不是,因此会返回不同的结果。但在 PHP 中并非如此。 @jie:您可能想使用=== 而不是==,因为'0XAB' == '0xab' 是真的。 使用 === 而不是 == 很重要,因为使用 == 将任何字符串与 0 进行比较都会返回 true,这显然是错误的...... @Kenny 还有 '0xAB' == '171' 【参考方案1】:

如果您想订购/比较字符串lexicographically,可以使用strcmp()。如果您只想检查是否相等,那么== 就可以了。

【讨论】:

喜欢usort。事实上,它非常适合排序。 @Charles 谢谢。***让我眼前一亮。 为了更清楚地排序。如果 string1 在 string2 之前排序,则 strcmp() 返回 0,如果它们相同,则返回 0。例如 $string_first = "aabo"; $string_second = "aaao";回声 $n = strcmp($string_first,$string_second);将返回大于零,因为 aaao 在 aabo 之前排序。 @postfuturist 我确定这是一个错字,他们的意思是===【参考方案2】:

之所以使用它是因为strcmp

如果 str1 小于 str2,则返回 如果 str1 大于 str2 则为 0,如果它们相等则为 0。

=== 只返回truefalse,它不会告诉你哪个是“更大”的字符串。

【讨论】:

icic tho 在我目前的情况下,我不需要知道哪个字符串更大:) strcmp 匹配字符串耗时 0.207852 秒 strcmp 不匹配字符串耗时 0.215276 秒 === 匹配字符串耗时 0.067122 秒 === 字符串不匹配耗时 0.057305 秒 snipplr.com/view/758 strcmp 的另一种用法是显示排序。为了更清楚地排序。如果 string1 在 string2 之前排序,strcmp() 返回 0,如果它们相同,则返回 0。例如 $string_first = "aabo"; $string_second = "aaao";回声 $n = strcmp($string_first,$string_second);将返回大于零,因为 aaao 在 aabo 之前排序。 为什么这个答案得到最多的支持?我投了反对票,因为虽然这是这个问题应得的答案,但不是“正确”的答案。正如很多人在其他答案中已经说过的那样,正确的答案应该是“使用 ===”。 @onur güngör 实际上,这 确实 回答了操作员的问题,即So is there any reason to use strcmp() ?,而 Postfuturist 的回答没有。哦,见鬼……似乎没有一个答案可以立即编译strcmp()使用===性能,以及糟糕的可靠性 of == 用于字符串比较...所以我将我的添加到列表中。【参考方案3】:

使用== 可能很危险。

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

例子:

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

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

不过,建议使用===,因为测试表明它比strcmp() 及其不区分大小写的替代方案strcasecmp() 快一点。

快速谷歌搜索大喊这个速度比较:http://snipplr.com/view/758/

【讨论】:

有时它会将它们转换为不同的类型,即使它们已经具有相同的类型。 即使比较两个表示整数的字符串,如"012" == "12",php 也会将两个字符串的类型更改为整数12 == 12,然后返回true @GoTo:这在后来的 PHP 版本中没有改变吗? @PeterMortensen 不知道。目前我不写PHP。【参考方案4】:

您不应该使用== 进行字符串比较。 === 可以。

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

只要运行上面的代码,你就会明白为什么了。

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

现在好多了。

【讨论】:

== 不仅仅是不同类型的问题。即使两边都是字符串,它有时也会给出意想不到的结果。试试 '1e3' == '1000' 0 == 'password123' 是怎么回事? @AndyLobel PHP 使用奇怪的松散比较规则将“password123”强制为一个数字,因为另一个操作数是一个数字,该字符串与大多数字符串一样,强制为数字 0,并且 PHP 为比较。 快速 var_dump((int)'password123');帮助我完全理解为什么会发生这种情况...**尴尬**...我真的很喜欢 === 运算符 这是因为如果两个操作数之一可转换为数字,则使用 '==',php 将两个操作数转换为数字,如果将非数字字符串转换为数字,则需要值为零,结果等于零,因此与简单的 '==' 比较的结果可能是不需要的【参考方案5】:

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

原因是它有错误报告所说的错误 - Bug #53999strcmp() doesn't always return -1, 0, or 1

【讨论】:

如果字符串相等,它将始终返回 0。 +1 表示小心关心除 0 以外的任何其他值。【参考方案6】:

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

例如'1e3' == '1000' 返回真。你应该改用===

【讨论】:

@Roman 是的,但是很多 PHP 程序员不知道他们必须这样做。因此发出警告。 @Antimony 那么为什么不告诉他们他们应该在你的回答中做什么呢?【参考方案7】:

嗯...根据这个PHP bug report,你甚至可以得到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,如果它们相等,则返回 0”。没有提到 Null 是一种可能性,但在诸如 substr 手册页之类的页面上却提到了它。 叹息 但是当表单方法是 post ... 时会发生同样的情况吗? @NikhilGeorge 确实如此,这里有问题的函数是 strcmp。与哪些输入进行比较并不重要。 虽然错误报告说可以返回 null,但这是不正确的。从 PHP 4.3 到 PHP 7.3 的所有官方 PHP 版本都不会从这些函数返回 null。我怀疑它可能是 alpha 或 beta 版本,并且无论关闭的 bug 是否无效,它都已修复。有关详细信息,请参阅3v4l.org/Zq8tM,这表明它确实会影响 HHVM 3.11 - 3.19。【参考方案8】:

永远记住,在比较字符串时,应该使用=== 运算符(严格比较)和not == 运算符(松散比较)。

【讨论】:

其实,我觉得比较anything时应该使用===【参考方案9】:

此外,该功能还可以帮助进行排序。为了更清楚地排序。如果 string1 在 string2 之前排序,strcmp() 返回小于 0,如果 string2 在 string1 之前排序,则返回大于 0,如果它们相同,则返回 0。例如

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

函数将返回大于零的值,因为 aaaoaabo 之前排序。

【讨论】:

【参考方案10】:

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

示例代码:Speed Test: strcmp vs ===

【讨论】:

【参考方案11】:

总结所有答案:

== 对于字符串比较来说是一个坏主意。 在许多情况下,它会给你“令人惊讶”的结果。不要相信它。

=== 很好,会给你最好的性能。

如果您需要确定哪个字符串“更大”,则应使用strcmp(),通常用于排序操作。

【讨论】:

【参考方案12】:

在 PHP 中,不使用字母排序,而是使用字符的 ASCII 值进行比较。

小写字母比大写字母具有更高的 ASCII 值。最好使用身份运算符 === 进行这种比较。 strcmp() 是一个执行二进制安全字符串比较的函数。它接受两个字符串作为参数,如果 str1 小于 str2,则返回 0 如果 str1 大于 str2,如果它们相等则为 0。还有一个名为 strcasecmp()不区分大小写版本,它首先将字符串转换为小写,然后进行比较。

【讨论】:

【参考方案13】:

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

【讨论】:

以上是关于使用 '==' 与 'strcmp()' 进行字符串比较的主要内容,如果未能解决你的问题,请参考以下文章

strcmp - '[' 标记之前的预期主表达式

C语言中:strcmp函数如何使用?

C语言函数strcmp()(比较两个字符串)

字符串函数的使用与模拟实现

C语言问题。。。strcmp怎么运用啊?

C语言学习字符串操作函数——————>strlen strcpy strcmp 详解与手动实现