Strcmp Equivelant for Integers (Intcmp) in PHP

strcmp equivelant for integers (intcmp) in PHP

Sort your data with:

function sortScripts($a, $b)
{
return $a['order'] - $b['order'];
}

Use $b-$a if you want the reversed order.

If the numbers in question exceed PHP's integer range, return ($a < $b) ? -1 : (($a > $b) ? 1 : 0) is more robust.

PHP and proper way of using the strcmp function

The "===" and "!==" comparison operators assert two things:

  1. The values are equal, and
  2. The values are of the same type

The short answer to your question "what is the point of using !== with the strcmp function" is simply "it's good practice". That's really the only reason regarding strcmp specifically, and != would give you the exact same result when it comes to that function.

The long answer is as follows:

PHP is traditionally a loosely typed language. That is, datatypes were not all that important and PHP implicitly cast types for you automatically. It still does this by default (although lots of stuff has been added to improve the situation over recent years). For example, if you add the string "1" to the integer 1, PHP will cast the string to an integer automatically and return the integer value 2. Strongly typed languages would return an error if you tried to do that. Another example is that PHP will cast 0 to boolean false and any other non-zero value to boolean true.

It's that second example that causes problems with some of PHP's built-in functions. For example, the strpos() function. If you check the documentation page for strpos you'll see a big "Warning" in the "Return Values" section stating "This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE". For that reason it advises you to use the "===" operator to make sure you are getting the exact value and type that you expect. So "=== 0" means the string was found at the beginning of the input, and "=== false" means the string was not found. If you just used "== false" you won't be distinguishing between the string being found at the beginning of the input and the string not being found at all (because 0 will be implicitly cast to boolean false for the "if" statement).

So, developers got into the habit of testing for equality and type by using "===" and "!==". It's a good habit.

Since strcmp always return an integer, and you are always comparing it to an integer, there is no implicit casting and so comparing types as well as equality is not neccessary.

PHP: Strcmp returns value -58 even though the 2 strings seem identical?

Credits to @CBroe who introduced var_dump to me! :)

I added the following lines of code

var_dump($current_file_name, $scriptname);
var_dump(basename($_SERVER['SCRIPT_NAME'],".php"));

into my function echoActiveClassIfPageIsActive.

function echoActiveClassIfPageIsActive($scriptname)
{
$current_file_name = $_SERVER['SCRIPT_NAME'];
var_dump($current_file_name, $scriptname);
var_dump(basename($_SERVER['SCRIPT_NAME'],".php"));
if (strcmp($current_file_name, $scriptname) == 0)
echo 'class="active"';
}

Turns out,

  • $current_file_name was string(10)=" index.php"
  • $scriptname was string(9)="index.php"

Hence, strcmp($current_file_name, $scriptname) did not return a value of 0. The 2 strings were not identical, unlike what I thought. basename($current_file_name) and $scriptname are the identical strings.

This is how I realised my error. Just thought I might share this thought process.

PHP strcmp not giving correct output

1 is less than 2, strcmp is defined as returning:

Returns < 0 if str1 is less than str2; > 0 if str1 is greater than
str2, and 0 if they are equal.

Thus the behaviour is expected.


Note the following caveat:

If you rely on strcmp for safe string comparisons, both parameters
must be strings, the result is otherwise extremely unpredictable. For
instance you may get an unexpected 0, or return values of NULL, -2, 2,
3 and -3.

From a comment on the documentation page for strcmp.


PHP is full of this sort of unexpected behaviour. In your situation, I would ensure both arguments were cast as strings to avoid any confusion:

$first = 1;
$second = 2;
echo strcmp((string)$first, (string)$second);

String comparison using '==' or '===' vs. 'strcmp()'

The reason to use it is because strcmp

returns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal.

=== only returns true or false, it doesn't tell you which is the "greater" string.

php usort() results in strange result

function sortScripts($a, $b)
{
return $a['order'] - $b['order'];
}

Use $b-$a if you want the reversed order.

If the numbers in question exceed PHP's integer range, return ($a < $b) ? -1 : (($a > $b) ? 1 : 0) is more robust.

You can check this link for more understanding strcmp equivelant for integers (intcmp) in PHP

Comparing strings, containing space with == in PHP

It all seems to go back to this is_numeric_string_ex C function.

To start at the implementation of ==:

ZEND_API int ZEND_FASTCALL compare_function(zval *result, zval *op1, zval *op2) {
...
switch (TYPE_PAIR(Z_TYPE_P(op1), Z_TYPE_P(op2))) {
...
case TYPE_PAIR(IS_STRING, IS_STRING):
...
ZVAL_LONG(result, zendi_smart_strcmp(op1, op2));

If both operands are a string, it ends up calling zendi_smart_strcmp...

ZEND_API zend_long ZEND_FASTCALL zendi_smart_strcmp(zval *s1, zval *s2) {
...
if ((ret1 = is_numeric_string_ex(Z_STRVAL_P(s1), Z_STRLEN_P(s1), &lval1, &dval1, 0, &oflow1)) &&
(ret2 = is_numeric_string_ex(Z_STRVAL_P(s2), Z_STRLEN_P(s2), &lval2, &dval2, 0, &oflow2))) ...

Which calls is_numeric_string_ex...

/* Skip any whitespace
* This is much faster than the isspace() function */
while (*str == ' ' || *str == '\t' || *str == '\n' || *str == '\r' || *str == '\v' || *str == '\f') {
str++;
length--;
}
ptr = str;

Which has explicit code to skip whitespace at the beginning, but not at the end.



Related Topics



Leave a reply



Submit