PHP字符串函數之 strcmp strncmp strcasecmp strncasecmp strnatcmp strnatcasecmp

PHP字符串函數之 strcmp strncmp strcasecmp strncasecmp strnatcmp strnatcasecmp


  • strcmp – 二進制安全字符串比較
  • strncmp – 二進制安全比較字符串開頭的若干個字符
  • strcasecmp – 二進制安全比較字符串(不區分大小寫)
  • strncasecmp – 二進制安全比較字符串開頭的若干個字符(不區分大小寫)
  • strnatcmp – 使用“自然順序”算法比較字符串
  • strnatcasecmp – 使用“自然順序”算法比較字符串(不區分大小寫)

strcmp

二進制安全字符串比較

int strcmp ( string $str1 , string $str2 )

參數說明

str1
第一個字符串。
str2
第二個字符串。

返回值

如果 str1 小於 str2 返回 < 0; 如果 str1 大於 str2 返回 > 0;如果兩者相等,返回 0。

注意

注意該比較區分大小寫。

示例

<?php
echo strcmp("Hello", "hello"); // -1
echo strcmp("5", 5);       // 0
echo strcmp("15", 0xf);    // 0
echo strcmp(61529519452809720693702583126814, 61529519452809720000000000000000); //0
echo strcmp(NULL, false);  // 0
echo strcmp(NULL, "");     // 0
echo strcmp(NULL, 0);      // -1
echo strcmp(false, -1);    // -2
echo strcmp("15", NULL);   // 2
echo strcmp(NULL, "foo");  // -3
echo strcmp("foo", NULL);  // 3
echo strcmp("foo", false); // 1
echo strcmp("foo", 5);     // 1
/*
NULL + PHP Warning 
strcmp() expects parameter 2 to be string, array given in ...
*/
echo strcmp("foo", array()); 
/*
NULL + PHP Warning 
strcmp() expects parameter 2 to be string, object given in ...
*/
echo strcmp("foo", new stdClass);
/*
NULL + PHP Warning 
strcmp() expects parameter 1 to be string, object given in ...
*/
echo strcmp(function(){}, "");
這裏會有同學有疑問,其他的還可以理解,但是
strcmp(61529519452809720693702583126814, 61529519452809720000000000000000); //0
比較結果竟然是相等,那麼PHP內部是怎麼執行的呢?
我們寫一個PHP腳本,就執行這個函數,然後用gdb調試一下看看

[root@localhost rasp]# gdb php
(gdb) set args -f ./strcmp.php
(gdb) b zif_strcmp 
Breakpoint 1 at 0x7c63e0: file /usr/local/src/php-5.5.15/Zend/zend_builtin_functions.c, line 495.
(gdb) r
Starting program: /usr/bin/php -f ./strcmp.php
[Thread debugging using libthread_db enabled]
Detaching after fork from child process 43348.
[New Thread 0x7ffff13f6700 (LWP 43349)]
[Thread 0x7ffff13f6700 (LWP 43349) exited]

Breakpoint 1, zif_strcmp (ht=2, return_value=0x7ffff78b85c8, return_value_ptr=0x0, this_ptr=0x0, return_value_used=1) at /usr/local/src/php-5.5.15/Zend/zend_builtin_functions.c:495
495 {
Missing separate debuginfos, use: debuginfo-install glibc-2.12-1.149.el6.x86_64 keyutils-libs-1.4-5.el6.x86_64 krb5-libs-1.10.3-33.el6.x86_64 libcom_err-1.41.12-21.el6.x86_64 libgcc-4.4.7-11.el6.x86_64 libpng-1.2.49-1.el6_2.x86_64 libselinux-2.0.94-5.8.el6.x86_64 libstdc++-4.4.7-11.el6.x86_64 libtool-ltdl-2.2.6-15.5.el6.x86_64 libxml2-2.7.6-17.el6_6.1.x86_64 nss-softokn-freebl-3.14.3-18.el6_6.x86_64 openssl-1.0.1e-30.el6_6.4.x86_64 zlib-1.2.3-29.el6.x86_64
(gdb) layout src

gdb

ZEND_FUNCTION(strcmp)
{
    zval **s1, **s2;

    if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &s1, &s2) == FAILURE) {
        ZEND_WRONG_PARAM_COUNT();
    }
    convert_to_string_ex(s1);
    convert_to_string_ex(s2);
    RETURN_LONG(zend_binary_zval_strcmp(*s1, *s2));
}
(gdb) n
(gdb) n
(gdb) n
(gdb) p s1
$1 = 0x1241500 "6.152951945281E+31"
(gdb) p s2
$2 = 0x1241560 "6.152951945281E+31"
(gdb) 
原來在PHP內部s1和s2 都被轉爲了 "6.152951945281E+31" 來比較的,有效數字爲前13位,所以相等。

strncmp

二進制安全比較字符串開頭的若干個字符

int strncmp ( string $str1 , string $str2 , int $len )

該函數與 strcmp() 類似,不同之處在於你可以指定兩個字符串比較時使用的長度

參數說明

str1
第一個字符串。
str2
第二個字符串。
len
用於比較的字符數

返回值

如果 str1 小於 str2 返回 < 0; 如果 str1 大於 str2 返回 > 0;如果兩者相等,返回 0。

注意

注意該比較區分大小寫。

示例

echo strncmp("xybc","a3234",0); // 0 
echo strncmp("abcdef","abc",3); // 0
echo strncmp("abcdef","abc",4); // 1

strcasecmp

二進制安全比較字符串(不區分大小寫)

int strcasecmp ( string $str1 , string $str2 )

該函數與 strcmp() 函數類似,不同之處在於不區分大小寫,其他可參考 strcmp()

參數說明

str1
第一個字符串。
str2
第二個字符串。

返回值

如果 str1 小於 str2 返回 < 0; 如果 str1 大於 str2 返回 > 0;如果兩者相等,返回 0。

示例

echo strcasecmp("Hello","hello"); // 0

strncasecmp

二進制安全比較字符串(不區分大小寫)

int strncasecmp ( string $str1 , string $str2 , int $len )

該函數與 strcasecmp() 類似,不同之處在於你可以指定兩個字符串比較時使用的長度
該函數與 strncmp() 也類似,不同之處在於不區分大小寫

參數說明

str1
第一個字符串。
str2
第二個字符串。
len
用於比較的字符數

返回值

如果 str1 小於 str2 返回 < 0; 如果 str1 大於 str2 返回 > 0;如果兩者相等,返回 0。

示例

echo strncasecmp("Hello","hello", 5); // 0
echo strncasecmp("abcdef","ABC",3);   // 0

strnatcmp

使用自然排序算法比較字符串

int strnatcmp ( string $str1 , string $str2 )

該函數實現了以人類習慣對數字型字符串進行排序的比較算法,這就是“自然順序”。

參數說明

str1
第一個字符串。
str2
第二個字符串。

返回值

與其他字符串比較函數類似,如果 str1 小於 str2 返回 < 0; 如果 str1 大於 str2 返回 > 0;如果兩者相等,返回 0。

注意

注意該比較區分大小寫。

示例

//我們來測試一下什麼是“以人類習慣”
echo strnatcmp("img10.png","img2.png"); // 1 說明該函數認爲 img10.png 大於 img2.png 與人類習慣一致
echo strcmp("img10.png","img2.png"); // -1 說明該函數認爲 img10.png 小於 img2.png,計算機思維
//在來看一個更直觀的例子
echo '<pre>';

$arr1 = $arr2 = array(
"img1.png",
"img2.png",
"img10.png",
"img01.png",
"img100.png",
"img20.png",
"img30.png",
"img200.png");

echo "標準字符串比較"."<br>";
usort($arr1,"strcmp");
print_r($arr1);

echo "自然序列字符串比較"."<br>";
usort($arr2,"strnatcmp");
print_r($arr2);

/*
標準字符串比較Array
(
    [0] => img01.png
    [1] => img1.png
    [2] => img10.png
    [3] => img100.png
    [4] => img2.png
    [5] => img20.png
    [6] => img200.png
    [7] => img30.png
)
自然序列字符串比較Array
(
    [0] => img01.png
    [1] => img1.png
    [2] => img2.png
    [3] => img10.png
    [4] => img20.png
    [5] => img30.png
    [6] => img100.png
    [7] => img200.png
)
*/

strnatcasecmp

使用“自然順序”算法比較字符串(不區分大小寫)

int strnatcasecmp ( string $str1 , string $str2 )

該函數實現了以人類習慣對數字型字符串進行排序的比較算法。除了不區分大小寫,該函數的行爲與 strnatcmp() 類似。

參數說明

str1
第一個字符串。
str2
第二個字符串。

返回值

與其他字符串比較函數類似,如果 str1 小於 str2 返回 < 0; 如果 str1 大於 str2 返回 > 0;如果兩者相等,返回 0。

示例

//我們將上面例子中 img2.png改爲大寫
echo '<pre>';
$arr1 = $arr2 = array("img1.png","IMG2.png","img10.png","img01.png","img100.png","img20.png","img30.png","img200.png");

echo "自然序列字符串比較 strnatcmp"."<br>";
usort($arr2,"strnatcmp");
print_r($arr2);

echo "自然序列字符串比較 strnatcasecmp"."<br>";
usort($arr2,"strnatcasecmp");
print_r($arr2);
/*
自然序列字符串比較 strnatcmpArray
(
    [0] => IMG2.png
    [1] => img01.png
    [2] => img1.png
    [3] => img10.png
    [4] => img20.png
    [5] => img30.png
    [6] => img100.png
    [7] => img200.png
)
自然序列字符串比較 strnatcasecmpArray
(
    [0] => img01.png
    [1] => img1.png
    [2] => IMG2.png
    [3] => img10.png
    [4] => img20.png
    [5] => img30.png
    [6] => img100.png
    [7] => img200.png
)
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章