比较字符串,包含 space 和 PHP 中的 ==
Comparing strings, containing space with == in PHP
我很好奇为什么会发生在 PHP:
'78' == ' 78' // true
'78' == '78 ' // false
我知道使用 strcmp
或至少 ===
会更好。我还知道,当您将数字字符串与 ==
进行比较时,如果可能的话,它们会被转换为数字。我也可以接受前导 space 被忽略,所以 (int)' 78'
是 78,第一种情况的答案是正确的,但我真的很困惑为什么第二种情况是错误的。
我认为 '78'
被转换为 78
,'78 '
被转换为 78
,所以它们是相同的,答案是正确的,但是显然,事实并非如此。
任何帮助将不胜感激!非常感谢您! :)
'78' 末尾的 space 导致 PHP 将变量视为字符串。您可以使用 trim() 去除 spaces.
一切仿佛回到了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;
其中有明确的代码可以在开头跳过空格,但在结尾没有。
我很好奇为什么会发生在 PHP:
'78' == ' 78' // true
'78' == '78 ' // false
我知道使用 strcmp
或至少 ===
会更好。我还知道,当您将数字字符串与 ==
进行比较时,如果可能的话,它们会被转换为数字。我也可以接受前导 space 被忽略,所以 (int)' 78'
是 78,第一种情况的答案是正确的,但我真的很困惑为什么第二种情况是错误的。
我认为 '78'
被转换为 78
,'78 '
被转换为 78
,所以它们是相同的,答案是正确的,但是显然,事实并非如此。
任何帮助将不胜感激!非常感谢您! :)
'78' 末尾的 space 导致 PHP 将变量视为字符串。您可以使用 trim() 去除 spaces.
一切仿佛回到了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;
其中有明确的代码可以在开头跳过空格,但在结尾没有。