29

我有一个将数字键作为字符串类型的 PHP 数组。

但是当我尝试访问它们时,PHP 给了我一个未定义的索引错误。

$a = (array)json_decode('{"1":1,"2":2}');
var_dump($a);
var_dump(isset($a[1]));
var_dump(isset($a["1"]));
var_dump($a[1]);
var_dump($a["1"]);

输出:

数组(大小=2)
    '1' => 整数 1
    '2' => 整数 2

布尔假

布尔假

错误:E_NOTICE:未定义的偏移量:1

空值

错误:E_NOTICE:未定义的偏移量:1

空值

如何访问这些值?

演示:http ://codepad.viper-7.com/8O03IM

4

6 回答 6

32

所以,我还没有看到任何其他答案涉及到这一点,但@xdazz 接近了。

让我们开始我们的环境,$obj等于解码字符串的对象表示法:

php > $obj = json_decode('{"1":1,"2":2}');

php > print_r($obj);
stdClass Object
(
    [1] => 1
    [2] => 2
)

php > var_dump( $obj );
object(stdClass)#1 (2) {
  ["1"]=>
  int(1)
  ["2"]=>
  int(2)
}

如果您想访问字符串,我们知道以下操作将失败:

php > echo $obj->1;

Parse error: parse error, expecting `T_STRING' or `T_VARIABLE' or `'{'' or `'$'' in php shell code on line 1

访问对象变量

您可以像这样访问它:

php > echo $obj->{1};
1

这与说:

php > echo $obj->{'1'};
1

访问数组变量

数组的问题是以下返回空白,这是类型转换的问题。

php > echo $obj[1];
php >

如果您将其类型转换回来,该对象将再次可访问:

php > $obj = (object) $obj;
php > echo $obj->{1};
1

这是一个可以为您自动执行上述操作的功能:

function array_key($array, $key){
    $obj = (object) $array;
    return $obj->{$key};
}

示例用法:

php > $obj = (array) $obj;
php > echo array_key($obj, 1);
1

php > echo array_key($obj, 2);
2
于 2012-09-13T01:51:17.190 回答
26

如果需要数组,请将json_decode的第二个参数设置为true.

$a = json_decode('{"1":1,"2":2}', true);

编辑: 当您将 std 对象转换为数组时,数字字符串键不会转换为数字。这是一个例子。

$obj = new stdClass;
$obj->{'1'} = 1;
$arr = (array) $obj;
var_dump($arr);
var_dump(isset($arr[1]));
于 2012-07-17T03:19:03.060 回答
15

显然,这是一个已知问题,并且没有修复它的计划;请参阅Doc Bug #45959 对象到数组的转换导致奇怪的行为

修复这意味着性能下降,因此最好将其保留为已知问题,但记录在案。

(然后)在数组类型的文档中指出了这种不稳定(强调我的):

如果将对象转换为数组,则结果是一个数组,其元素是对象的属性。键是成员变量名称,有一些值得注意的例外:整数属性不可访问......这可能导致一些意外行为......

于 2012-07-17T03:28:20.827 回答
1

是的。我同意,PHP 在从对象到数组的类型转换方面存在问题,但 foreach 正在智能地处理对象或关联数组。

$a = json_decode('{"1":1,"2":2}'); //need not typecast but doesnt break even if u typecast

foreach ($a as $k=>$v){
    echo $v;
}
于 2012-09-14T08:42:30.410 回答
1

我最近遇到了同样的问题。

$obj = new stdClass();
$obj->{'0'} = "test";

$array = (array)$obj;
foreach ($array as $key => $value) {
   $array[$key] = strtoupper($value);
}
var_dump($array);

此代码输出:

array(2) {
  ["0"]=>
  string(4) "test"
  [0]=>
  string(4) "TEST"
}

发现在调试将递归对象转换为数组的方法时,我已经疯了。

于 2012-09-14T21:27:20.147 回答
1

我有同样的问题(但使用array_intersect_key)。

这是我的解决方案:

$array = array_combine(array_keys($array), $array);
于 2013-09-10T15:07:02.257 回答