2015-08-31 21 views
6

io sono curioso di sapere perchè questo sta accadendo in PHP:Confronto tra stringhe, che contiene lo spazio con == in PHP

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

So che è molto meglio usare strcmp o meno ===. So anche che quando si confrontano stringhe numeriche con == vengono castate ai numeri, se possibile. Posso anche accettare che lo spazio iniziale sia ignorato, quindi (int)' 78' è 78, e la risposta è vera nel primo caso, ma sono davvero confuso perché è falso nel secondo.

ho pensato che '78' è realizzata mediante fusione per 78 e '78 ' è realizzata mediante fusione per 78, anche, in modo che siano la stessa e la risposta è vero, ma ovviamente, non è questo il caso.

Qualsiasi aiuto sarà apprezzato! Grazie mille in anticipo! :)

+3

Qui http://php.net/manual/fr/language.operators.comparison.php vedere la risposta di arnaud su arnapou dot net. È abbastanza bello – Hearner

+0

Grazie mille @Hearner, ma l'ho già letto prima di pubblicare la domanda qui. :) Mi stavo chiedendo perché "78" sia considerato "stringa numerica" ​​e lo spazio viene ignorato, ma in "78" viene preso in considerazione. – Faery

+0

fai un 'var_dump();' e/o 'print_r();' su entrambi e guarda cosa appare. Questo potrebbe spiegarlo a pieno titolo. –

risposta

7

Tutto sembra tornare a this is_numeric_string_ex C function.

consecutivi a partire dal 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)); 

Se entrambi gli operandi sono una stringa, si finisce per chiamare 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))) ... 

che chiede 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; 

Quale ha il codice esplicito per saltare lo spazio bianco all'inizio, ma non alla fine.

+1

Questo merita sicuramente un distintivo [** buona risposta **] (http://stackoverflow.com/help/badges/24/good-answer). (Forse inviarlo come modifica della pagina manuale? E aggiungi come una piccola nota "nota:" grigia) – Rizier123

+0

Grazie mille! Questo è proprio quello che stavo cercando! – Faery

+0

Ma se provate a confrontare ''78' == '78'' e'' 78 '== '78' 'come' 78 == '78'' e '78 == '78'' il ritorno sarà 'true' in entrambi i casi. Perché? Entrambi continuano ad essere 'stringa | integer'. –

-1

Lo spazio alla fine di '78 'fa sì che PHP tratti la variabile come una stringa. puoi usare trim() per rimuovere gli spazi.

+1

Grazie! So di 'trim()' e non userò mai il codice di cui sopra, stavo solo cercando la spiegazione e la logica del perché si comporta in questo modo. Per me "78" e "78" sono ugualmente "stringenti". Ancor di più, se li lanci entrambi in numeri interi, la risposta sarà 78 in entrambi i casi. – Faery

+1

Mentre hai risolto il problema e come risolverlo, questo non spiega la parte PERCHE 'come l'OP stava chiedendo. – Machavity