How Does PHP Compare Strings with Comparison Operators

How does PHP compare strings with comparison operators?

PHP will compare alpha strings using the greater than and less than comparison operators based upon alphabetical order.

  • In the first example, ai comes before i in alphabetical order so the test of > (greater than) is false - earlier in the order is considered 'less than' rather than 'greater than'.

  • In the second example, ia comes after i alphabetical order so the test of > (greater than) is true - later in the order being considered 'greater than'.

Confusion in comparing string with a number in php

You can see it in the php manual. https://www.php.net/manual/en/language.operators.comparison.php

When comparing a string, number or resource with another string, number or resource:

Translate strings and resources to numbers, usual math

Btw: '151000' is a string, not a number. 15100 would be a number.

How exactly php spaceship operator compare strings, arrays and objects

"Comparisons are performed according to PHP's usual type comparison rules (http://php.net/manual/en/types.comparisons.php)".

1) Yes, it uses the ASCII values

2) If the arrays are different lengths, the Array with fewer values is smaller.

Otherwise it compares the arrays key by key, giving "earlier" values priority. For example comparing $arr1[0] to $arr2[0] first. If $arr1 has a key that doesn't exist in $arr2, the arrays aren't comparable (eg if we're using non-numeric arrays).

// Arrays are compared like this with standard comparison operators
// $arr1 and $arr2 are arrays
function standard_array_compare($arr1, $arr2)
{
// If either array has more values, that array is considered "larger"
if (count($arr1) < count($arr2)) {
return -1; // $arr1 < $arr2
} elseif (count($arr1) > count($arr2)) {
return 1; // $arr1 > $arr2
}

//Otherwise compare the array values directly
foreach ($arr1 as $key => $val) {
if (!array_key_exists($key, $arr2)) {
return null; // uncomparable, these arrays do not have the same keys
} elseif ($val < $arr2[$key]) {
return -1; // $arr1 < $arr2
} elseif ($val > $arr2[$key]) {
return 1; // $arr1 > $arr2
}
}
return 0; // $arr1 == $arr2
}

Note, the above is not PHP's actual code, just an approximate representation of the logic used.

Essentially, then, it treats an array in a similar way to comparing a big-endian number. It compares $arr1[0] to $arr2[0]. If they are the different it returns -1 or 1 depending which is larger. If they are the same it moves on to $arr1[1] and $arr2[1]. If all values are the same it returns 0 (arrays are equal)

While not exactly the same, it might be simpler to consider [1,2,3] <=> [3,2,1] as basically equivalent to 123 <=> 321...

PHP: How does the Not-equal and Not-identical Operators work and are they faster then the Equal or Identical Operators?

Strings are defined as a structure here:

typedef struct {
char *c;
size_t len;
size_t a;
} smart_string;

The equality operator is defined here. (The following three equality operators also perform in essentially the same way, except they skip the address check as it would always be false)

static zend_always_inline zend_bool zend_string_equals(zend_string *s1, zend_string *s2)
{
return s1 == s2 || (ZSTR_LEN(s1) == ZSTR_LEN(s2) && !memcmp(ZSTR_VAL(s1), ZSTR_VAL(s2), ZSTR_LEN(s1)));
}

In case you don't speak C:

First, the address of each string structure is compared, if these are equal then the strings must be equal. Otherwise, further checks are made.

Second, if the addresses are not equal, then the length of each string is compared. This is just an integer equality check as the length is part of the string's structure definition. If the lengths are not equal, false is returned.

Next, the memory contents are checked for each string with memcmp. As memcmp returns 0 if the memory contents are equal, this is negated to return true.

To explicitly answer your question: PHP avoids checking every character of a string, the only case in which every character would be checked is that if every character of the string except for the last character is equal, and that the lengths of the strings are the same.

I must say: If you are really worrying about === being slower than !==, then you really shouldn't be.

Why does PHP convert a string with the letter E into a number?

"608E-4234" is the float number format, so they will cast into number when they compares.

608E-4234 and 272E-3063 will both be float(0) because they are too small.

For == in php,

If you compare a number with a string or the comparison involves
numerical strings, then each string is converted to a number and the
comparison performed numerically.

http://php.net/manual/en/language.operators.comparison.php

Attention:

What about the behavior in javascript which also has both == and ===?

The answer is the behavior is different from PHP. In javascript, if you compare two value with same type, == is just same as ===, so type cast won't happen for compare with two same type values.

In javascript:

608E-4234 == 272E-3063 // true
608E-4234 == "272E-3063" // true
"608E-4234" == 272E-3063 // true
"608E-4234" == "272E-3063" // false (Note: this is different form PHP)

So in javascript, when you know the type of the result, you could use == instead of === to save one character.

For example, typeof operator always returns a string, so you could just use

typeof foo == 'string' instead of typeof foo === 'string' with no harm.

PHP Comparison Not as I was expecting when comparing string that start with comma against zero as string

When comparing with the , at the start, you will find that the ascii value of , is 44 (decimal) whereas the ascii value for 0 is 48.

So with a comma, the string is less than because the ascii value is less than, without the comma it starts with c which has an ascii value of 99, which is greater than 0.

ASCII table used from https://www.asciitable.xyz/

How to correctly compare a string and an integer in PHP?

When you compare a number with something else, the other thing is first converted to a number, and then these two numbers are compared. So a comparison like "90" == 90 does what you expect -- it's equivalent to 90 == 90.

The problem you're having is that $node->nid is not a string, it's an object of class Drupal\Core\Field\FieldItemList. The class doesn't provide a method to convert this type to a number, so it's not able to perform the comparison.

However, it appears that this type has a method to convert to string. But PHP won't do a double conversion when performing the comparison. So you need to perform the object->string conversion explicitly, and then PHP will convert the string to an integer.

if (isset($node->nid) && (string)$node->nid == 90)

How do string comparison operators work in Twig?

This is easily reproductible :

{% set nav = true %}
{% if nav == "top" %}
ok
{% endif %}

Displays ok.

According to the documentation :

Twig allows expressions everywhere. These work very similar to regular
PHP and even if you're not working with PHP you should feel
comfortable with it.

And if you test in pure PHP the following expression :

$var = true;
if ($var == "top") {
echo 'ok';
}

It will also display ok.

The point is : you should not compare variables of different types. Here, you compare a bool with a string : if your string is not empty or if it does not contains only zeros, it will evaluate to true.

You can also have a look to the PHP manual to see how comparison are made with different types.

Edit

You can use the sameas test to make strict comparisions, and avoid type juggling matters.



Related Topics



Leave a reply



Submit