Сравнение строк, содержащих пробел с == в PHP


Мне любопытно, почему это происходит в PHP:

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

Я знаю, что гораздо лучше использовать strcmp или, по крайней мере, ===. Я также знаю, что когда вы сравниваете числовые строки с ==, они по возможности преобразуются в числа. Я также могу согласиться с тем, что начальное пространство игнорируется, поэтому (int)' 78' равно 78, и ответ верен в первом случае, но я действительно не понимаю, почему он ложен во втором.

Я думал, что '78' приведено к 78 и '78 ' также приведено к 78, таким образом, они одинаковы, и ответ верен, но очевидно, что это не так.

Любая помощь будет оценена по достоинству! Заранее большое вам спасибо!:)

Author: Faery, 2015-08-31

2 answers

Похоже, все это восходит к этой is_numeric_string_ex функции C.

Чтобы начать с реализации ==:

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));

Если оба операнда являются строкой, то в конечном итоге вызывается 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))) ...

Который вызывает 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;

, в котором есть явный код для пропуска пробелов в начале, , но не в конце.

 7
Author: deceze, 2015-08-31 12:45:07

Пробел в конце '78' заставляет PHP обрабатывать переменную как строку. вы можете использовать функцию обрезки() для удаления пробелов.

 -1
Author: Dale Hurley, 2015-08-31 12:04:43