PHP字符串比较

Posted

技术标签:

【中文标题】PHP字符串比较【英文标题】:PHP String Comparison 【发布时间】:2011-10-03 13:14:01 【问题描述】:

当我回显它们时,我有两个看起来相同的字符串,但是当我 var_dump() 它们时它们是不同的字符串类型:

Echo:
http://blah
http://blah
var dump:
string(14) "http://blah"
string(11) "http://blah"
strToHex:
%68%74%74%70%3a%2f%2f%62%6c%61%68%00%00%00
%68%74%74%70%3a%2f%2f%62%6c%61%68

当我比较它们时,它们返回 false。如何操作字符串类型,以便执行返回 true 的比较。字符串 11 和字符串 14 有什么区别?我确信有一个简单的解决方案,但还没有找到任何东西,无论我如何内爆、爆炸、UTF8 编码等,它们都不会比较或更改类型的字符串。

感谢您的帮助!

彼得。

【问题讨论】:

如果你trim()他们两个,他们会比较吗? 这些变量是怎么得到的,还有代码吗? blah 只是一个例子,还是真正的输出?您是否使用其他 Unicode 字符?空格等? 我正在做的是用 mcrypt 加密一些数据 string1。然后作为控制,我将加密数据解密为 string2,并将其与 string1 进行比较以确认加密/解密是正确的。这是 string1 "blah" 和 string2 "blah" 不比较的地方。当我回显它们时,它们看起来完全一样,但如果我对它们进行 md5 处理,它们就不同了。我可以看到字符串周围没有空格。将首先尝试更多这些建议。 加密后 beforeafter 的字符串是否带有 "\x00"?如果 after,那么这些字符可能会自动添加到字符串中,因此解密后的结果具有一些所需的长度。如果 before,那么加密库可能会将字符串视为 null-terminated 字符串并在第一个 "\x00" 字符处停止。 【参考方案1】:

您是否已经尝试trim 这些字符串?

if (trim($string1) == trim($string2)) 
 // do things

【讨论】:

如果是这种情况,var_dump 是否会显示一个空格(至少一个可见性)? 正如@gar_onn 所说,如果有连续的空格字符,var_dump 仅显示 1 个空格字符。无论如何,转储没有其他原因可以说这两个字符串的长度不同 但在问题中没有(甚至没有1个)空格字符 原始问题甚至没有格式化,这就是为什么我认为他没有考虑空间 @OZ_ 你的回答可以解释为什么这两个字符串在内容上是“不同的”,但在长度上却不一样?【参考方案2】:

字母“a”可以写成另一种编码。 例如:blаh - 这里a 是西里尔字母“а”。 所有这些字母都是西里尔字母,但看起来像拉丁文:у、е、х、а、р、о、с

【讨论】:

有任何关于为什么这些更长的参考资料吗?想了解更多信息? +1 因为我没有其他想法。但在作者的例子中,a 似乎不是西里尔字母 a。 @gar_onn 因为utf-8是多字节编码,每个符号可以占用1个字节以上。【参考方案3】:

请尝试http://php.net/manual/en/function.strcmp.php 进行字符串比较。

【讨论】:

【参考方案4】:

比较前先修剪字符串,有转义字符,如 \t 和 \n 是不可见的。

$clean_str = trim($str);

【讨论】:

如果问题只是字符串末尾的"\x00"字符,我建议使用rtrim($str, chr(0))。这将确保仅删除字符串末尾的空字符。【参考方案5】:

可能在上限范围内的 Unicode 字符串被计为双字节。

使用mb_strlen 检查长度。

还有一些字符可能不可见,但存在(有许多 unicode 空格等)

通常,当您使用 Unicode 函数时,您应该使用 mb_* 字符串函数。

您可以重载php.ini 中的字符串编码函数,以始终使用mb_* 函数而不是标准函数(不确定xdebug 是否支持这些设置)。

在 PHP 6 中这个问题将得到解决,因为它应该是全局 Unicode 感知的。

【讨论】:

这是找到长度的正确方法,但比较起来字符串总是不同的。他们应该是。【参考方案6】:

当使用var_dump() 时,string(14) 表示该值为string,其中包含14 字节。所以string(11)string(14) 不是不同的字符串“类型”,它们只是长度不同的字符串。

我会使用这样的东西来查看这些字符串中的实际内容:

function strToHex($value, $prefix = '') 
    $result = '';
    $length = strlen($value);
    for ( $n = 0; $n < $length; $n++ ) 
        $result .= $prefix . sprintf('%02x', ord($value[$n]));
    
    return $result;


echo strToHex("test\r\n", '%');

输出:

%74%65%73%74%0d%0a

这解码为:

%74 - t %65 - e %73 - 秒 %74 - t %0d - \r(回车) %0a - \n(换行)

或者,正如@Karolis 在 cmets 中指出的那样,您可以使用内置函数 bin2hex()

echo bin2hex("test\r\n");

输出:

746573740d0a

【讨论】:

只要尝试用\r\n var_dump 任何变量,你就会明白为什么这个建议是错误的。 其实有bin2hex()功能,不过推荐还是不错的。 @OZ_ 在任何情况下这种调试都会清楚地回答所有问题。 @OZ_,你能解释一下为什么这个建议是错误的吗?我知道var_dump() 输出什么,但我也知道作者说他的字符串是"blah"(没有\r,没有\n,没有其他字符)。如果他只看到"blah" 之外的任何内容,则值得检查这些字符串中的实际内容,而基本的echovar_dump() 无法做到这一点。就像@Karolis 所说,它将回答所有关于为什么这些字符串不同的问题。 @Karolis,我编辑了一个答案以包含bin2hex() - 不知道该功能。

以上是关于PHP字符串比较的主要内容,如果未能解决你的问题,请参考以下文章

== 在 PHP 中是区分大小写的字符串比较吗?

不考虑 PHP 顺序的字符串比较

php 弱类型总结

php中的字符串比较奇怪的行为

PHP字符串比较

php 字符串和数字比较一些问题