2015-08-31 131 views
6

與==的空間,我很好奇爲什麼發生這種情況在PHP中:比較字符串,包含在PHP

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

我知道,這是更好的使用strcmp或至少===。我也知道,如果您將數字字符串與==進行比較,則可能會將它們轉換爲數字。我也可以接受,領先空間被忽略,所以(int)' 78'是78,在第一種情況下答案是正確的,但我真的很困惑,爲什麼它在第二個是錯誤的。

我認爲'78'被強制轉換爲78'78 '被強制轉換爲78也一樣,所以它們是相同的,答案是真實的,但顯然,事實並非如此。

任何幫助將不勝感激!非常感謝您提前! :)

+3

Here http://php.net/manual/fr/language.operators.comparison.php在arnapou網點查看來自arnaud的答案。這非常好 – Hearner

+0

非常感謝@Hearner,但是在發佈問題之前,我已經閱讀了它。 :)我只是想知道爲什麼'78'被認爲是「數字串」並且空間被忽略,但在'78'中它被考慮在內。 – Faery

+0

在兩者上執行'var_dump();'和/或'print_r();'並查看顯示內容。這可以解釋它本身。 –

回答

7

這一切似乎都回到this is_numeric_string_ex C function

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

如果兩個操作數是一個字符串,它最終調用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; 

它有明確的代碼在開頭跳過空格,但不是最後。

+1

這肯定值得[**好回答**](http://stackoverflow.com/help/badges/24/good-answer)徽章。 (也許提交它作爲手動頁面編輯?並添加像一個灰色的小「注:」框) – Rizier123

+0

非常感謝!這正是我一直在尋找的! – Faery

+0

但是如果你試圖比較'78'=='78'和'78'== '78''就像'78 =='78''和'78 =='78'在這兩種情況下都是「真」。爲什麼?兩者都繼續是'string | integer'。 –

-1

'78'結尾的空格會導致PHP將該變量視爲一個字符串。你可以使用trim()去掉空格。

+1

謝謝!我知道'trim()',我永遠不會使用上面的代碼,我只是尋找解釋和邏輯爲什麼它的行爲如此。對我而言,'78'和'78''同樣是「絲毫」。更重要的是,如果你把它們都歸爲整數,那麼兩種情況下的答案都是78。 – Faery

+1

雖然您已經確定了問題以及如何解決問題,但這並不能解釋OP爲什麼會問這個問題。 – Machavity