使用PHP 5.3.5。不确定这在其他版本上是如何工作的。
我对使用包含数字的字符串感到困惑,例如'0x4B0'
或'1.2e3'
。 PHP如何处理这些字符串似乎与我不一致。只有我吗?或者这是一个错误?或未记录的功能?或者我只是在文档中遗漏了一些神奇的句子?
<?php
echo $str = '0x4B0', PHP_EOL;
echo "is_numeric() -> ", var_dump(is_numeric($str)); // bool(true)
echo "*1 -> ", var_dump($str * 1); // int(1200)
echo "(int) -> ", var_dump((int)$str); // int(0)
echo "(float) -> ", var_dump((float)$str); // float(0)
echo PHP_EOL;
echo $str = '1.2e3', PHP_EOL;
echo "is_numeric() -> ", var_dump(is_numeric($str)); // bool(true)
echo "*1 -> ", var_dump($str * 1); // float(1200)
echo "(int) -> ", var_dump((int)$str); // int(1)
echo "(float) -> ", var_dump((float)$str); // float(1200)
echo PHP_EOL;
在这两种情况下,is_numeric()
都会返回true
。此外,在这两种情况下,$str * 1
解析字符串并返回有效数字(在一种情况下为整数,在另一种情况下为float)。
使用(int)$str
和(float)$str
进行投射会产生意外结果。
(int)$str
在任何情况下都只能解析数字,前面有可选的“+”或“ - ”。(float)$str
更高级,可以解析类似^[+-]?\d*(\.\d*)?(e[+-]?\d*)?
的内容,即可选的“+”或“ - ”,后跟可选数字,后跟可选的小数点和可选数字,后跟可选指数由“e”组成,带有可选的“+”或“ - ”后跟可选数字。虽然在十六进制数据上失败。相关文档:
$str * 1
,但不适用于强制转换。为什么?$s * 10
和(int)$s * 10
表达式以相同的方式工作并返回相同的结果。但是,如示例所示,这些表达式的评估方式不同。1.2e3
是有效的数字数据。未提及符号(“+”或“ - ”)。它没有提到十六进制值。这与is_numeric()
中使用的“数字数据”的定义相冲突。然后,建议“有关此转换的更多信息,请参阅strtod(3)的Unix手册页”,man strtod
描述其他数值(包括HEX表示法)。那么,在阅读之后,十六进制数据是否应该是有效的或无效的数字数据?因此...
is_numeric()
和PHP在用作数字时如何处理字符串的方式之间是否存在(或者更确切地说应该存在)?(int)$s
,(float)$s
和$s * 1
的工作方式不同,即。当$s
为0x4B0
或1.2e3
?0x4B0
或1.2e3
? floatval()
根本不适用于HEX,intval()
需要将$base
设置为16
以使用HEX,使用(int)$str
和{{1}进行类型转换有时工作,有时不起作用,所以这些都不是有效的选择。我也没有考虑(float)$str
,因为它看起来更像数据操作而不是转换。在这种情况下,也不考虑自编函数,因为我正在寻找原生解决方案。答案 0 :(得分:3)
直接强制转换(int)$str
和(float)$str
根本不会有不同的工作方式:它们都会从字符串中读取尽可能多的字符,因为它们可以解释为相应类型的数字。
对于“0x4B0”,int转换读取“0”(OK),然后“x”并停止,因为它不能将“x”转换为整数。同样适用于浮动转换。
对于“1.2e3”,int转换为“1”(OK),然后为“。”。并停止。 float-conversion将整个字符串识别为有效的浮点符号。
像$str * 1
这样的表达式的自动类型识别比显式强制转换更灵活。显式强制转换要求整数和浮点数采用%i
中%f
和printf
生成的格式。{/ p>
或许您可以使用intval和floatval而不是显式的强制转换为int,以获得更大的灵活性。
最后,您的问题“是十六进制数据应该是有效还是无效的数字数据?”很尴尬。没有“十六进制数据”这样的东西。十六进制只是一个数字基础。 和36。 [抱歉,那是BS。 PHP中没有strtoul
。但是strtoul
具有相同的功能,请参见上文。]
答案 1 :(得分:2)
intval
使用strtol在base
参数为零时识别oct / hex前缀,所以
var_dump(intval('0xef')); // int(0)
var_dump(intval('0xff', 0)); // int(255)
答案 2 :(得分:1)
是否存在(或者更确切地说,应该存在)is_numeric()与PHP在将字符串用作数字时如何处理它们之间的关系?
PHP中没有名为 numeric 的数据类型,is_numeric()
函数更像是可以被PHP解释为数字的测试。
就这样的数字解释而言,在值前添加+
实际上会使PHP将其转换为数字:
$int = +'0x4B0';
$float = +'1.2e3';
您会发现in the manual for string, look for the section String conversion to numbers解释了这一点。
由于它是由运算符触发的,我认为没有必要为什么在PHP中应该有一个函数来执行相同的操作。那将是多余的。
内部PHP使用名为zendi_convert_scalar_to_number
的函数作为add运算符(可假设+
),它将使用is_numeric_string
来获取数字。
当与字符串一起使用时,is_numeric()
会在内部调用完全相同的函数。
因此,要触发本机转换功能,我只需使用+
运算符。这将确保您将返回数字伪类型(int或float)。