PHP整数数组索引真的是数字吗?

8
考虑这个例子。
<?php
    $test = array("00"=>"A","B","C","D","E");
    print_r($test);
    echo "<br>";

    echo $test[0];
    echo "<br>";
    echo $test["0"];
    echo "<br>";

    echo $test["00"];
    echo "<br>";
    echo $test[00];
?>

输出

数组 ( [00] => A [0] => B [1] => C [2] => D [3] => E )

B

B

A

B

问题1. 为什么$test[0]$test["0"]相同,而$test[00]$test["00"]不同?

问题2. 如果问题1的答案是因为数字上00 = 0,那么为什么这个数组有一个索引为00,另一个索引为0

问题3. 如果无法使用$test[0]访问$test["00"],那么如何知道哪个索引是数字,哪个是字符串?如果两者都只是数字

编辑内容

根据目前的答案,我脑海中又出现了另一个问题。以下是问题4。

问题4. 为什么if(00==0)是真的,而if(07==7)是假的?(对于数组索引)

问题5.

$test = array("00"=>"A","0"=>"B","000"=>"C","0000"=>"D","00000"=>"E");
 echo $test[0];

为什么输出是B,而不是A?因为在数组中,第一个元素位于0位置。
3个回答

5
根据文档,其中一个“将发生的关键转换”是: String中包含有效的integer将被转换为integer类型。例如,密钥"8"实际上将存储在8下。另一方面,"08"不会被转换,因为它不是有效的十进制整数。
[link]

但是他们如何宣称08在数学上不等于8呢? 08应该是数字8的有效值,为什么00等于0,而08却不等于8? - Hanky Panky
2
所以问题4的答案是(07==7)为真!但是当涉及到数组索引时,“07”!= 7。 - fsw
如果按照您的论点,00是一个字符串,那么为什么PHP会将其评估为“true”?if(7=="07") - Hanky Panky
你可以使用var_dump($test)来查看数组中的实际内容。设置元素时,获取数组元素的索引规则也适用。例如,array("0"=>"A", 0=>"B") 实际上是一个只有一个元素 "B" 的数组。 - fsw
更准确的说法是:仅当强制转换回来会产生相同的字符串时,字符串才会被转换为整数类型。显然,“0” ===(string)(int)“0”,但“00”!==(string)(int)“00”。因此,在此上下文中,每个整数值只有一个被认为是有效的字符串。 - donquixote
显示剩余11条评论

2
Q1. 因为数值上 00 = 0。
Q2. 因为索引是“00”,而不是 00。
尝试:
$test=array(00=>"A","B","C","D","E");
print_r($test);

/*
Array
(
    [0] => A
    [1] => B
    [2] => C
    [3] => D
    [4] => E
)
*/

Q3.
echo gettype("00");
# string
echo gettype(00);
# integer
echo gettype("0");
# string
echo gettype(0);
# integer

从手册中: http://php.net/manual/zh/language.types.array.php 字符串包含有效整数将被强制转换为整数类型。例如,键“8”实际上将存储在8下。另一方面,“08”不会被转换,因为它不是有效的十进制整数。
在评论后编辑: Q4. 我认为OP的问题本质上是为什么第二个和第四个行为不同:
php > var_dump("00" === 0);
bool(false)
php > var_dump(00 === 0);
bool(true)
php > var_dump("08" === 8);
bool(false)
php > var_dump(08 === 8);
bool(false)

我还没有答案。

如果0和"0"之间的区别是不存在的,那么00和"00"之间的区别是什么? - Hanky Panky
但是他们如何宣称数学中的08与8不同呢?08应该是数字8的有效值,为什么00等于0,但08却不等于8呢? - Hanky Panky
3
以0开头的数字是八进制数,因此010 == 8。 08 是无效的八进制数,会被解释为0,因此var_dump(08 == 0)的输出结果为bool(true) - yaz

-1
"anystring" == 0; //true
"0000" == 0;      //true

"0" == 0;      //true

这是错误的。任何不以数字开头的字符串都会被计算为零。换句话说,你的第三个语句是错误的。("1" == 0); //false - yaz

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