如何使用PHP创建包含JSON的数据的JSON,而不在JSON中包含一堆转义字符,并且不首先将JSON转换为数组或对象,然后再转换回JSON?
<?php
/*
GIVEN: Data from DB contained in array $a.
I know that sometimes JSON shouldn't be stored in a DB, but please assume this is a good case for doing so.
*/
$a[0]=json_encode(['a'=>5,'b'=>'hello']);
$a[1]=json_encode(['a'=>2,'b'=>'how are you']);
$a[2]=json_encode(['a'=>7,'b'=>'goodby']);
$o=[
['x'=>321,'y'=>$a[0]],
['x'=>123,'y'=>$a[1]],
['x'=>111,'y'=>$a[2]],
];
echo('<pre>'.print_r($o,1).'</pre>');
echo(json_encode($o));
/*
Undesired result containing a bunch of escape characters. Granted, they are benign, however, will increase network trafic.
[{"x":321,"y":"{\"a\":5,\"b\":\"hello\"}"},{"x":123,"y":"{\"a\":2,\"b\":\"how are you\"}"},{"x":111,"y":"{\"a\":7,\"b\":\"goodby\"}"}]
*/
$o=[
['x'=>321,'y'=>json_decode($a[0])],
['x'=>123,'y'=>json_decode($a[1])],
['x'=>111,'y'=>json_decode($a[2])],
];
echo('<pre>'.print_r($o,1).'</pre>');
echo(json_encode($o));
/*
Desired result, however, is there a more efficient way to do this?
[{"x":321,"y":{"a":5,"b":"hello"}},{"x":123,"y":{"a":2,"b":"how are you"}},{"x":111,"y":{"a":7,"b":"goodby"}}]
*/
答案 0 :(得分:0)
不,没有更快的方法可以再次进行解码,变异和编码。
然而,您可以将解码代码与数据库查询紧密结合。如果你有一个数据模型类,你可以在那里进行解码,这样调用这个服务的代码永远不会看到JSON,但总是看到解码后的数据。
然后,再次,在您写入数据库的数据模型中,您将在最后一刻执行JSON编码。
这样您就可以隐藏数据层墙后面的JSON因子,而应用程序的其余部分则不必了解它。
另一种解决方案包括编写一个可以兼顾JSON的库,提供在JSON中设置值的可能性,而不需要调用者解码/编码。此选项需要更多代码(或者您可以找到现有库),因此这不是我的第一个建议。但这是一个可以存在于该库中的函数的简单示例:
function json_set($json, $path, $value) {
$arr = json_decode($json, true);
$ref =& $arr;
$props = explode("/", $path);
$finalProp = array_pop($props);
foreach ($props as $key) {
if (!isset($ref[$key])) $ref[$key] = [];
$ref =& $ref[$key];
}
$obj = json_decode($value);
$ref[$finalProp] = $obj ? $obj : $value;
return json_encode($arr);
}
这允许您提供现有的JSON字符串,指向该JSON内某个点的路径,以及应该放在那里的值。该值本身也可以是JSON。
根据您从数据库中获取的 $ a 中的JSON值,以下是如何在您的情况下使用它:
$o=json_encode([
['x'=>321],
['x'=>123],
['x'=>111],
]);
$o = json_set($o, '0/y', $a[0]);
$o = json_set($o, '1/y', $a[1]);
$o = json_set($o, '2/y', $a[2]);
echo $o;
输出:
[{"x":321,"y":{"a":5,"b":"hello"}},
{"x":123,"y":{"a":2,"b":"how are you"}},
{"x":111,"y":{"a":7,"b":"goodby"}}]