(数组)类型转换奇怪的行为对象到数组转换

时间:2016-04-06 08:09:42

标签: php json

早些时候我有一些代码块,它工作正常,但在某些情况下它会抛出PHP注意事项:

以下是代码:

$json = '{"1455260079":"Tracking : #34567808765098767 USPS","1455260723":"Delivered","1455261541":"Received Back"}';

$json_obj = json_decode($json);
$json_array = (array) $json_obj;
var_dump($json_array);
print_r($json_array);

echo $json_array["1455260079"]."\n";

输出:

array(3) {
  ["1455260079"]=>
  string(34) "Tracking : #34567808765098767 USPS"
  ["1455260723"]=>
  string(9) "Delivered"
  ["1455261541"]=>
  string(13) "Received Back"
}
Array
(
    [1455260079] => Tracking : #34567808765098767 USPS
    [1455260723] => Delivered
    [1455261541] => Received Back
)

Notice: Undefined index: 1455260079 in /in/PULrp on line 14

所以我用下面的代码更改了上面的代码,它工作正常。

$json_array = json_decode($json, true);
var_dump($json_array);
print_r($json_array);
echo $json_array["1455260079"]."\n";

输出:

array(3) {
  [1455260079]=>
  string(34) "Tracking : #34567808765098767 USPS"
  [1455260723]=>
  string(9) "Delivered"
  [1455261541]=>
  string(13) "Received Back"
}
Array
(
    [1455260079] => Tracking : #34567808765098767 USPS
    [1455260723] => Delivered
    [1455261541] => Received Back
)
Tracking : #34567808765098767 USPS

但是我有点困惑为什么(array)类型转换在这段代码中不起作用。我知道json_decode($json, true)是将json字符串转换为数组的最佳选择,但$json_array = (array) $json_obj;也是一个有效选项。

在查看两个代码的var_dump时,它显示了一些差异,但两个数组的print_r完全相同。

我很想知道为什么在var_dump两者中发生了这种差异,以及(array)类型转换在第一种情况下如何将对象转换为数组?

我还注意到,如果密钥是数字,即我的情况下为1455260079,如果我将密钥1455260079更改为某个字符串,它会按预期工作,则会发生这种情况。

您可以在https://3v4l.org/PULrp

看到完整代码的输出

1 个答案:

答案 0 :(得分:3)

我在这里有一些发现:

引自:

  1. A numeric string as array key in PHP
  2. http://www.php.net/manual/en/language.types.array.php
  3. 他们说:

      

    包含有效整数的字符串将强制转换为整数类型。例如。键“8”实际上将存储在8下。另一方面,“08”将不会被强制转换,因为它不是有效的十进制整数。

    有趣的是(略微修改您的测试脚本):

    <?php
    $json = '{"1455260079":"Tracking : #34567808765098767 USPS","1455260723":"Delivered","1455261541":"Received Back"}';
    
    $json_obj = json_decode($json);
    $json_array = (array) $json_obj;
    var_dump($json_array);
    print_r($json_array);
    
    $newerArray = array();
    
    echo "json_array contents: \n";
    foreach($json_array as $k => $v){
        echo "k: $k " . gettype($k) . ", v: $v " . gettype($v) . "\n";
        $newerArray[$k] = $v;
    }
    
    echo "\n";
    
    echo "newerArray contents: \n";
    foreach($newerArray as $k => $v){
        echo "k: $k " . gettype($k) . ", v: $v " . gettype($v) . "\n";
    }
    
    echo $json_array["1455260079"]."\n";
    echo $newerArray["1455260079"]."\n";
    

    输出结果为:

    array(3) {
      ["1455260079"]=>
      string(34) "Tracking : #34567808765098767 USPS"
      ["1455260723"]=>
      string(9) "Delivered"
      ["1455261541"]=>
      string(13) "Received Back"
    }
    Array
    (
        [1455260079] => Tracking : #34567808765098767 USPS
        [1455260723] => Delivered
        [1455261541] => Received Back
    )
    json_array contents: 
    k: 1455260079 string, v: Tracking : #34567808765098767 USPS string
    k: 1455260723 string, v: Delivered string
    k: 1455261541 string, v: Received Back string
    
    newerArray contents: 
    k: 1455260079 integer, v: Tracking : #34567808765098767 USPS string
    k: 1455260723 integer, v: Delivered string
    k: 1455261541 integer, v: Received Back string
    
    Notice: Undefined offset: 1455260079 in /in/Eq1OI on line 24
    
    Tracking : #34567808765098767 USPS
    

    注意两个数组中键的类型 - 来自阵列的数组有{numeric} string个键,而重新分配的数组有integer个键。

    当您将对象强制转换为数组时,该键仍然是string。根据上面的引用,这不是数组的PHP定义所期望的。

    因此,当您尝试使用“数字字符串”访问数组时,PHP仍然将string视为integer,但在内部,键仍然是字符串,从而导致未定义的数组。

    这也意味着对于关联数组,关键比较实际上是严格的,但实际上是松散的