为啥 unset() 会改变 json_encode 格式化字符串的方式?

Posted

技术标签:

【中文标题】为啥 unset() 会改变 json_encode 格式化字符串的方式?【英文标题】:Why does unset() change the way json_encode formats the string?为什么 unset() 会改变 json_encode 格式化字符串的方式? 【发布时间】:2015-08-20 15:50:19 【问题描述】:

我今天使用unset() 和 json_decode/json_encode 发现了一些有趣的东西。代码如下:

echo "<h3>1) array as string</h3>";
$sa = '["item1","item2","item3"]';
var_dump($sa);
echo "<h3>2) array as string decoded</h3>";
$sad = json_decode($sa);
var_dump($sad);
echo "<h3>3) array as string decoded, then encoded again. <small>(Note it's the same as the original string)</small></h3>";
$sade = json_encode($sad);
var_dump($sade);
echo "<h3>4) Unset decoded</h3>";
unset($sad[0]);
var_dump($sad);
echo "<h3>5) Encode unset array. <small>(Expecting it to look like original string minus the unset value)</small></h3>";
$ns = json_encode($sad);
var_dump($ns);
echo "<h3>6) Decode Encoded unset array</h3>";
var_dump(json_decode($ns));

结果:

所以我的问题是:为什么 unset() 会改变 json_encode 使其成为字符串的方式?以及如何实现和原来一样的字符串格式?

【问题讨论】:

【参考方案1】:

在数字 5 中,如果您注意到键从 1 开始。通常数组(在 php 和 js/json 中)从零开始。 json 中的非零索引数组(或具有非连续数字的数组)是对象文字,而不是数组。如果您想要相同的字符串格式,我建议您 json_decode 传递第二个参数以将其强制为数组。然后,您可以使用数组函数将数组重新索引为数字,例如 array_shift 或 array_pop。或者在对数组进行 json_encoding 时,使用 array_values 自己重新索引数组。

【讨论】:

换一种方式,JS 没有关联数组,所以json_encode() 将其转换为对象以保留您的键。【参考方案2】:

json 不需要包含从偏移量零开始的连续键序列的键。

从标准枚举数组中取消设置值会在该数组的键序列中留下间隙,它不会以任何方式调整剩余的键;所以 json 需要通过包含键来反映这种差异

如果您想再次将键重置为从偏移量 0 开始的连续序列,那么

unset($sad[0]);
$sad = array_values($sad);

然后再次进行 json 编码/解码

Demo

【讨论】:

以上是关于为啥 unset() 会改变 json_encode 格式化字符串的方式?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 json_encode 会返回一个空字符串

多维数组json_encode之后产生对象而不是数组问题

多维数组json_encode之后产生对象而不是数组问题

多维数组json_encode之后产生对象而不是数组问题

json_encode 的斜线问题。为啥以及如何解决它?

Json_encode 改变我的查询顺序