Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Comparing strings, containing space with == in PHP

I am curious why this is happening in PHP:

'78' == ' 78' // true
'78' == '78 ' // false

I know that it's much better to use strcmp or the least ===. I also know that when you compare numerical strings with == they are casted to numbers if possible. I also can accept that the leading space is ignored, so (int)' 78' is 78, and the answer is true in the first case, but I'm really confused why it's false in the second.

I thought that '78' is casted to 78 and '78 ' is casted to 78, too, so they are the same and the answer is true, but obviously, that's not the case.

Any help will be appreciated! Thank you very much in advance! :)

like image 304
Faery Avatar asked Aug 31 '15 11:08

Faery


People also ask

How do you check if a string contains a space in PHP?

PHP | ctype_space() Function A ctype_space() function in PHP is used to check whether each and every character of a string is whitespace character or not. It returns True if the all characters are white space, else returns False.

Can you use == to compare strings in PHP?

The most common way you will see of comparing two strings is simply by using the == operator if the two strings are equal to each other then it returns true. This code will return that the strings match, but what if the strings were not in the same case it will not match.

Can you compare strings with ==?

You should not use == (equality operator) to compare these strings because they compare the reference of the string, i.e. whether they are the same object or not. On the other hand, equals() method compares whether the value of the strings is equal, and not the object itself.

How do you compare strings with spaces?

String normalString = "ABCDEF"; String stringWithSpaces = " AB CD EF "; We can simply compare them while ignoring the spaces using the built-in replaceAll() method of the String class: assertEquals(normalString. replaceAll("\\s+",""), stringWithSpaces.


1 Answers

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.

like image 52
deceze Avatar answered Oct 02 '22 17:10

deceze