CodingBison

We discuss PHP functions that compare strings. We begin with a short description of these functions. Next, we provide several code-examples to look into behavior of these functions.

 /* All of these functions return an integer */

 $int_comparison = strcmp($string_variable1, $string_variable2);
 $int_comparison = strncmp($string_variable1, $string_variable2, $size_n);

 $int_comparison = strcasecmp($string_variable1, $string_variable2);
 $int_comparison = strncasecmp($string_variable1, $string_variable2, $size_n);

 $int_comparison = strnatcmp($string_variable1, $string_variable2);
 $int_comparison = strnatcasecmp($string_variable1, $string_variable2);

The first two functions (strcmp() and strncmp()) in the above list do a simple comparison of two strings. strcmp() returns 0, greater than 0, or less than 0 if the string $string_variable1 is same, or greater than, or less than string $string_variable2 respectively; please note for the case of unequal strings, the returned value may not necessarily be +1 or -1. strncmp() is similar to that of strcmp(), except that the comparison is done only for the first "$size_n" characters of string $string_variable1. If "size_n" is greater than the length of either one of the strings, then comparison is made only till the length of the shorter string.

The next two functions (strcasecmp() and strncasecmp()) compare two strings by ignoring the case of strings. strcasecmp() is similar to strcmp(), but with one difference. This function converts both the strings to lower case before it compares them; because of this conversion, the case-related differences between the two strings goes away. Likewise, strncasecmp() is a case-insensitive variant of strncmp().

The last two functions (strnatcmp() and strnatcasecmp()) compare two strings in natural order, i.e. they take into account both numeric and string part of a variable. Thus, in natural ordering, "social_200.txt" is less than "social_1000.txt" because after the common string "social_", the number 200 is less than 1000. If we were to use strcmp() to compare these two strings, then strcmp() would evaluate that "social_200.txt" is greater than "social_1000.txt" because the string "2" appears after "1". strnatcmp() compares strings in a natural order. strnatcasecmp() is a case-insensitive variant of strnatcmp().

Having described these string-comparison functions, let us now take a look at some implementations that illustrate their behavior.

Our first implementation discusses strcmp() and strncmp(). We use strcmp() to compare two strings that are same and then, to compare two strings that are different. Next, we use strncmp() to compare two strings that have a common substring. The example also uses strlen() to compute the length of a string.

 <?php
 $var_str1 = "The Social Network";
 $var_str2 = "The Social Network";
 $var_str3 = "The Social Norm";

 /* Let us compare $var_str1 and $var_str2 -- these strings are same */
 $result_cmp = strcmp($var_str1, $var_str2);
 echo "[strcmp]: Comparing 1 and 2: $result_cmp <br>";

 /* Let us compare $var_str1 and $var_str3 -- these strings are different */
 $result_cmp = strcmp($var_str1, $var_str3);
 echo "[strcmp]: Comparing 1 and 3: $result_cmp <br>";

 /* Let us compare the identical parts of $var_str1 and $var_str3 ("The Social N") */
 $size_comp = strlen("The Social N");
 $result_cmp = strncmp($var_str1, $var_str3, $size_comp); 
 echo "[strncmp]: Comparing $size_comp characters of 1 and 3: $result_cmp <br>";
 ?>

The output of this program is as follows.

 [strcmp]: Comparing 1 and 2: 0 
 [strcmp]: Comparing 1 and 3: -10 
 [strncmp]: Comparing 12 characters of 1 and 3: 0 

Let us summarize the above output. Since $var_str1 and $var_str2 are same strings, strcmp() returns 0. However, $var_str1 and $var_str3 are not same. The string "The Social Norm" is greater than the string "The Social Network" since after the "The Social N" substring, the character 'o' has a higher ASCII value than the character 'e' in $var_str1. Therefore, comparing $var_str1 and $var_str3 returns -1 (meaning that the first string is "smaller" than the second string). However, when we compare only the first 12 characters, which is common for $var_str1 and $var_str3, the strncmp() returns 0.

Our second implementation discusses strcasecmp() and strncasecmp(). For this, we change the upper-case characters of $var_str2 and $var_str3 from above example to lower-cases. With this change, $var_str1 and $var_str2 become different and strcmp() fails. However, strcasecmp() and strncasecmp() are case insensitive and hence, they succeed.

 <?php
 $var_str1 = "The Social Network";
 $var_str2 = "the social network";
 $var_str3 = "the social norm";

 $result_cmp1 = strcmp($var_str1, $var_str2); 
 echo "[strcmp]: Comparing 1 and 2: $result_cmp1 <br>";

 $result_cmp2 = strcasecmp($var_str1, $var_str2); 
 echo "[strcasecmp]: Comparing 1 and 2: $result_cmp2 <br>";

 $result_cmp3 = strcasecmp($var_str1, $var_str3); 
 echo "[strcasecmp]: Comparing 1 and 3: $result_cmp3 <br>";

 $size_comp = strlen("The Social N");
 $result_cmp4 = strncasecmp($var_str1, $var_str2, $size_comp); 
 echo "[strncasecmp]: Comparing $size_comp characters of 1 and 3: $result_cmp4 <br>";
 ?>

We provide the output below:

 [strcmp]: Comparing 1 and 2: -1
 [strcasecmp]: Comparing 1 and 2: 0
 [strcasecmp]: Comparing 1 and 3: -10
 [strncasecmp]: Comparing 12 characters of 1 and 3: 0 

Our third implementation discusses strnatcmp() and strnatcasecmp(). Since these functions use natural ordering, we use strings that contain both numeric and string parts.

In this example, strcmp() looks at dictionary ordering and finds that "90 dollars" is greater than "100 dollars" since the number "9" comes after "1" in the dictionary. However, with strnatcmp(), this behavior is modified -- strnatcmp() uses natural ordering and evaluates that "90 dollars" is less than "100 dollars". Next, we use strnatcasecmp() to demonstrate that it treats both "90 dollars" and "90 Dollars" as equals.

 <?php
 $var_90dollars  = "90 dollars";
 $var_100dollars = "100 dollars";
 $var_90Dollars  = "90 Dollars";

 /* strcmp() */
 $result_comparison = strcmp($var_90dollars, $var_100dollars); 
 echo "[strcmp]: Comparing \$var_90dollars and \$var_100dollars: $result_comparison <br>";

 /* strnatcmp() */
 $result_comparison = strnatcmp($var_90dollars, $var_100dollars); 
 echo "[strnatcmp]: Comparing \$var_90dollars and \$var_100dollars: $result_comparison <br>";

 $result_comparison = strnatcmp($var_90dollars, $var_90Dollars); 
 echo "[strnatcmp]: Comparing \$var_90dollars and \$var_90Dollars: $result_comparison <br>";

 /* strnatcasecmp() */
 $result_comparison = strnatcasecmp($var_90dollars, $var_100dollars); 
 echo "[strnatcasecmp]: Comparing \$var_90dollars and \$var_100dollars: $result_comparison <br>";

 $result_comparison = strnatcasecmp($var_90dollars, $var_90Dollars); 
 echo "[strnatcasecmp]: Comparing \$var_90dollars and \$var_90Dollars: $result_comparison <br>";
 ?>

The output (provided below) demonstrates the usefulness of strnatcmp() and strnatcasecmp() functions.

 [strcmp]: Comparing $var_90dollars and $var_100dollars: 8 
 [strnatcmp]: Comparing $var_90dollars and $var_100dollars: -1 
 [strnatcmp]: Comparing $var_90dollars and $var_90Dollars: 1 
 [strnatcasecmp]: Comparing $var_90dollars and $var_100dollars: -1 
 [strnatcasecmp]: Comparing $var_90dollars and $var_90Dollars: 0 

Note that since the ASCII value of 'D' is smaller than that of 'd', string, "90 dollars" is greater than that of "90 Dollars"!

In addition to the above string comparison functions, we can also use PHP's generic equality operators for comparing strings: "==" and "===". These operators can test other types of PHP variables as well.

Out of two variables, if one variable is a string and the other is not, then operator "==" casts the non-string variable to a string variable; after that, it proceeds with comparison. However, operator "===" is stricter and does not typecast the non-string variable to string. Instead, based on the type difference itself, it evaluates that the variables are different. Thus, operator "===" not only compares the values but also the types of the variables.

Here is a simple program that illustrate this behavior:

 <?php
 $var_str100 = "100"; /* $var_str100 is a string */
 $var_int100 = 100;   /* $var_int100 is an integer */

 if ($var_str100 == $var_int100) 
     echo "[==] \$var_str100 and \$var_int100 are same <br>";
 else 
     echo "[==] \$var_str100 and \$var_int100 are NOT same <br>";

 if ($var_str100 === $var_int100) 
     echo "[===] \$var_str100 and \$var_int100 are same <br>";
 else 
     echo "[===] \$var_str100 and \$var_int100 are NOT same <br>";
 ?>

The output of the following snippet is as follows. Clearly, operator "==" is a more liberal equality test than operator "==="!

 [==] $var_str100 and $var_int100 are same 
 [===] $var_str100 and $var_int100 are NOT same 




comments powered by Disqus