问题描述
我正在尝试理解 PHP 中的数字字符串。 我有以下代码:
var_dump(5 * "10 abc");
var_dump(is_numeric("10 abc"));
这给了我输出:
int(50)
bool(false)
这让我很困惑,因为字符串 "10 abc" 在第一个表达式中似乎被解释为数字字符串(因此是 int(50) 输出,并且没有关于使用非数字值的警告),但是当执行 is_numeric() 函数时,它返回 false,表明它实际上不是数字字符串。
我花了一些时间浏览文档以了解这种行为,但找不到任何具体的答案,有人可以帮助解释导致这种行为的原因吗?
我知道 PHP 8.0.0 对数字字符串进行了一些更改,但这是我现在正在尝试理解的 PHP 7.1.33。
解决方法
此处被 PHP 8.0 接受的“Saner numeric string”RFC 的 RFC 作者。
#cont {
background-color: #F8F9FA;
position: relative;
}
#cont:before {
left: calc((50vw - 50%) * -1);
background: #F8F9FA;
content: '';
display: block;
position: absolute;
width: calc(50vw - 50%);
top: 0;
bottom: 0;
}
#cont:after {
right: calc((50vw - 50%) * -1);
background: #F8F9FA;
content: '';
display: block;
position: absolute;
width: calc(50vw - 50%);
top: 0;
bottom: 0;
}
是不是一个数字字符串,而是一个前导-numeric string,意思是字符串的开头看起来像一个数字,但它不是'第一个是因为在字符串中的某个点存在乱码(这包括空格)。
因为 "10 abc"
根据 PHP 的定义检查值是否被视为数字(在 PHP 8.0 之前意味着前导空格后跟 + 或 - 符号以及任何整数、普通十进制数或指数表示法中的数字),它将在字符串上返回 is_numeric()
,这些字符串只是被认为是前导数字。
然而,算术运算尝试将它们的操作数转换为适当的数字类型(int 或 float),因此 false
被转换为 "10 abc"
因为 PHP 会将前导数字字符串转换为它的前导数值。
在 technical background section of the PHP RFC 中可以找到更多“有趣”的细节和边缘情况。
,我认为理解您描述的行为的最简单方法是,仅仅因为字符串不是数字,并不意味着它不能被强制或视为数字强>.
你的第一行代码
var_dump(5 * "10 abc");
将字符串视为数字,一旦遇到无效字符,它就会忽略之后的所有内容。
你的另一行代码
var_dump(is_numeric("10 abc"));
实际上表现得更聪明,并像人类一样问自己,我们在这里处理的是数字字符串;答案是否定的(因为相同的无效字符)。