PHP数组unset()后,将PHP json_encode作为对象

23

我在使用unset删除数字数组键后,发现json_encode出现了奇怪的行为。以下代码可以清楚地说明问题。我已经从CLI和Apache模块中运行过它:

PHP版本信息:

C:\Users\usr\Desktop>php -v
PHP 5.3.1 (cli) (built: Nov 20 2009 17:26:32)
Copyright (c) 1997-2009 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2009 Zend Technologies

PHP 代码

<?php

$a = array(
    new stdclass,
    new stdclass,
    new stdclass
);
$a[0]->abc = '123';
$a[1]->jkl = '234';
$a[2]->nmo = '567';

printf("%s\n", json_encode($a));
unset($a[1]);
printf("%s\n", json_encode($a));

程序输出

C:\Users\usr\Desktop>php test.php
[{"abc":"123"},{"jkl":"234"},{"nmo":"567"}]
{"0":{"abc":"123"},"2":{"nmo":"567"}}

你可以看到,第一次将 $a 转换为 JSON 时,它被编码为 JavaScript 数组。第二次(在 unset 调用后) $a 被编码为 JavaScript 对象。这是为什么,我应该如何防止这种情况发生?


+1 因为看到一个好问题很棒。 :) - Spudley
3个回答

21

这是因为您的数组中有一个空洞:它有索引0和2,但缺少了1。JSON无法编码带有空洞的数组,因为数组语法不支持索引。

您可以编码 array_values($a) 来代替,它将返回重新索引的数组。


你可以在删除一个元素后对数组进行排序。 - NullUserException
@NullUserException 虽然这将产生一个副作用,即对您的数组进行排序。 - zneak
对于那些想了解unset行为的人,请查看以下链接并向下滚动至“有用的函数”:http://us3.php.net/manual/en/language.types.array.php“unset()函数允许从数组中删除键。请注意,该数组将不会重新索引。” - leepowers
@NullUserException 很棒的添加!无论如何都需要对数组进行排序——一举两得。 - sjkm

7

除了使用array_values技术外,还可以使用array_splice来一步删除元素并重新索引:

unset($a[1]);

相反:

array_splice($a, 1, 1);

1
绝对完美的方式完成工作,而不会弄乱集合,谢谢! - CookieMonster
1
这是最优雅的方式。 - DQM

2

尝试使用JSON_FORCE_OBJECT选项进行json_encode,例如:json_encode($a, JSON_FORCE_OBJECT),这样您将始终获得相同的结果。


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