2015-08-31 14 views
6

Jestem ciekaw dlaczego tak się dzieje w PHP:porównywania ciągów zawierających przestrzeń == PHP

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

wiem, że to o wiele lepiej jest użyć strcmp lub najmniejszą ===. Wiem też, że jeśli porównasz ciągi liczbowe z ==, są one rzutowane na liczby, jeśli to możliwe. Mogę też zaakceptować, że wiodąca przestrzeń jest ignorowana, więc (int)' 78' ma 78, a odpowiedź jest prawdziwa w pierwszym przypadku, ale jestem naprawdę zdezorientowana, dlaczego jest fałszywa w drugim.

Myślałem, że '78' jest lanego do 78 i '78 ' jest lanego do 78 też, więc są one takie same, a odpowiedź jest prawdziwa, ale oczywiście, że nie jest to przypadek.

Każda pomoc zostanie doceniona! Z góry bardzo dziękuję! :)

+3

Tutaj http://php.net/manual/fr/language.operators.comparison.php zobacz odpowiedź od arnaud at arnapou dot net. Jest całkiem niezły – Hearner

+0

Bardzo dziękuję @Hearner, ale przeczytałem go już przed opublikowaniem pytania tutaj. :) Właśnie się zastanawiałem, dlaczego "78" jest uważane za "ciąg liczbowy", a spacja jest ignorowana, ale w '78 'jest brana pod uwagę. – Faery

+0

Wykonaj 'var_dump();' i/lub 'print_r();' na obu i zobacz, co się pojawi. To może wyjaśniać to samo w sobie. –

Odpowiedz

7

Wszystko wydaje się powracać do numeru this is_numeric_string_ex C function.

Aby uruchomić w 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)); 

Jeśli oba operandy są ciąg, to kończy się wywołaniem 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))) ... 

który wzywa 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; 

Który ma wyraźny kod, aby pominąć białe znaki na początku, , ale nie na końcu.

+1

To zdecydowanie zasługuje na odznakę [** good-answer **] (http://stackoverflow.com/help/badges/24/good-answer). (Może przesłać go jako ręczną edycję strony i dodać jak mały szary "Uwaga:") – Rizier123

+0

Dziękuję bardzo! Tego właśnie szukałem! – Faery

+0

Ale jeśli spróbujesz porównać ''78' == '78'' i'' 78 '== '78' 'jak' 78 == '78'' i '78 == '78'' powrót będzie "true" w obu przypadkach. Czemu? Oba w dalszym ciągu to 'string | liczba całkowita ". –

-1

Przestrzeń na końcu '78 'powoduje, że PHP traktuje zmienną jako ciąg znaków. możesz użyć funkcji trim(), aby usunąć spacje.

+1

Dzięki! Wiem o "trim()" i nigdy nie użyję powyższego kodu, szukałem tylko wyjaśnienia i logiki, dlaczego zachowuje się w ten sposób. Dla mnie ''78'' i' '78' 'są jednakowo" sztywne ". Co więcej, jeśli rzucisz obie na liczby całkowite, odpowiedź będzie wynosić 78 w obu przypadkach. – Faery

+1

Podczas gdy problem został rozwiązany i jak go rozwiązać, nie wyjaśnia to dlaczego część, o której pytał OP. – Machavity

Powiązane problemy