将字符串转换为整数

18

我的代码

<?php
var_dump('0xD' * 1 );
var_dump((int)'0xD');
var_dump(intval('0xD'));
var_dump((float)'0xD');

实际结果:

int(13)
int(0)
int(0)
float(0)

为什么前两个条件的结果不同?你能提供正确的文档吗?
我找到的所有内容如下: 类型转换:在PHP中,类型转换的工作方式与C语言类似:所需类型的名称写在要转换的变量之前的括号中。当在某些类型之间进行转换时,可能并不明显会发生什么。有关更多信息,请参见以下章节:... 转换为整数:从字符串: 请参阅字符串转换为数字 字符串转换为数字 当在数值上下文中计算字符串时,将确定以下结果和类型。
因此,据我理解,文档说直接转换为int和将其放入数字上下文中应该是相同的。我的错误在哪里?
添加:在回答之前,请尝试检查第一个和第二个代码(和输出)。
2个回答

11

'0xD'是一个字符串。文档清楚地指定如何将字符串“转换”为整数值(在此选择(int) '0xD';作为示例):

当字符串在数字上下文中进行评估时,结果值和类型如下确定。

如果字符串不包含字符'.'、'e'或'E',并且数值适合整数类型限制(由PHP_INT_MAX定义),则该字符串将被评估为整数。在所有其他情况下,它将被评估为浮点数。

该值由字符串的初始部分给出。如果字符串以有效的数字数据开头,则使用此值。否则,该值将为0(零)。有效的数字数据是可选符号,后跟一个或多个数字(可选包含小数点),后跟一个可选的指数。指数是'e'或'E'后跟一个或多个数字。

字符串'0xD'的初始部分是一个数字0,因此它是(int) 0

不要将其与编写代码混淆。如果您在代码中编写它,它不是一个字符串,而是一个整数数字的十六进制表示/符号(演示):

<?php

$value = eval("return 0xD;");

var_dump($value); # int(13)

这并没有完全回答为什么表达式'0xD' * 1的结果是(int) 13,但解释了到目前为止的所有内容,并说明了在PHP中适用的两个整数值解释规则。
我认为,在PHP中将字符串转换为整数和整数上下文之间存在细微差别。如果表示十六进制数字的字符串在整数/浮点数上下文中使用:
'0xD' * 1

在这个表达式中,由于*运算符和1操作数(参见Type Juggling),字符串'0xD'将被评估为数字。这不是类型转换,因为没有类型转换语言结构。
看起来在这个表达式的情况下,将字符串解释为整数按照指定字面量进行,但与进行转换时不同。
有人可能会认为何时应用转换,何时应用字面解释仍未记录。然而,使用类型转换可以解决任何此类问题(Demo):
<?php

$value = '0xD';

var_dump($value); # string(3) "0xD"
var_dump($value * 1); # int(13)
var_dump((int) $value * 1); # int(0)

问题是为什么第一段代码返回13(它也应该使用这些文档)。 - RiaD
@RiaD:我明白你的意思了,我在答案中补充了一些缺失的部分。我找到了一个叫做“整数字面量的正式结构”的东西,它与这里发生的情况类似。 - hakre
好的,但是类型转换强制类型转换都被称为类型转换。现在其他程序员和我可以测试这个行为了,但我认为文档中缺少这些信息是PHP开发人员的懒惰。 - RiaD
@RiaD:事情可能没有你想象的那么简单,所以最好尊重别人已经为你做的一切,特别是PHP开发人员。您可以帮助改进文档,这可能会帮助您学到更多,并更好地理解正在发生的事情。关于文档,有一个词:相信地形,而不是地图。如果遇到这样的具体问题,最好查看PHP源代码。这确实是一个非常小的方面,文档说明如果您想要特定类型,则应使用类型转换。 - hakre
哦,也许今天我太过激了。谢谢回答。 - RiaD

2
显然是引号的问题。
<?php
var_dump('0xD' * 1 );
var_dump((int) 0xD);
var_dump(intval(0xD));
var_dump((float) 0xD);

提供

int(13)
int(13)
int(13)
float(13)

我认为PHP将字符串中的十六进制值视为不可能的整数。

正如您所看到的,我代码中的所有0xD都在引号中,但第一个字符串被转换为13,第二个字符串被转换为0。 - RiaD
第一个实际上是由*字符转换的;PHP似乎在乘法的上下文中理解它是一个十六进制整数,但当强制转换时,它只看到一个没有整数或浮点值的字符串。你认为呢? - Pelshoff
好问题!毫无头绪 :P 你怎么找到这个问题的? - Pelshoff
这个问题让我做了一些测试。 - RiaD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接