我正在构建一个PHP脚本,将JSON数据提供给另一个脚本。我的脚本将数据构建到一个大型关联数组中,然后使用json_encode输出数据。下面是一个脚本示例:
$data = array('a' => 'apple', 'b' => 'banana', 'c' => 'catnip');
header('Content-type: text/javascript');
echo json_encode($data);
上面的代码产生如下输出:
{"a":"apple","b":"banana","c":"catnip"}
如果你有少量的数据,这是很好的,但我更喜欢这样的东西:
{
"a": "apple",
"b": "banana",
"c": "catnip"
}
有没有办法在PHP中做到这一点,而不需要丑陋的黑客?似乎Facebook的某个人发现了这一点。
以下是对我有效的方法:
test.php的内容:
<html>
<body>
Testing JSON array output
<pre>
<?php
$data = array('a'=>'apple', 'b'=>'banana', 'c'=>'catnip');
// encode in json format
$data = json_encode($data);
// json as single line
echo "</br>Json as single line </br>";
echo $data;
// json as an array, formatted nicely
echo "</br>Json as multiline array </br>";
print_r(json_decode($data, true));
?>
</pre>
</body>
</html>
输出:
Testing JSON array output
Json as single line
{"a":"apple","b":"banana","c":"catnip"}
Json as multiline array
Array
(
[a] => apple
[b] => banana
[c] => catnip
)
还要注意html中“pre”标签的使用。
希望这能帮助到别人
我从Composer: https://github.com/composer/composer/blob/master/src/Composer/Json/JsonFile.php和nicejson: https://github.com/GerHobbelt/nicejson-php/blob/master/nicejson.php中获取代码
Composer代码很好,因为它从5.3到5.4的更新很流畅,但它只编码对象,而nicejson需要json字符串,所以我合并了它们。代码可以用来格式化json字符串和/或编码对象,我目前在Drupal模块中使用它。
if (!defined('JSON_UNESCAPED_SLASHES'))
define('JSON_UNESCAPED_SLASHES', 64);
if (!defined('JSON_PRETTY_PRINT'))
define('JSON_PRETTY_PRINT', 128);
if (!defined('JSON_UNESCAPED_UNICODE'))
define('JSON_UNESCAPED_UNICODE', 256);
function _json_encode($data, $options = 448)
{
if (version_compare(PHP_VERSION, '5.4', '>='))
{
return json_encode($data, $options);
}
return _json_format(json_encode($data), $options);
}
function _pretty_print_json($json)
{
return _json_format($json, JSON_PRETTY_PRINT);
}
function _json_format($json, $options = 448)
{
$prettyPrint = (bool) ($options & JSON_PRETTY_PRINT);
$unescapeUnicode = (bool) ($options & JSON_UNESCAPED_UNICODE);
$unescapeSlashes = (bool) ($options & JSON_UNESCAPED_SLASHES);
if (!$prettyPrint && !$unescapeUnicode && !$unescapeSlashes)
{
return $json;
}
$result = '';
$pos = 0;
$strLen = strlen($json);
$indentStr = ' ';
$newLine = "\n";
$outOfQuotes = true;
$buffer = '';
$noescape = true;
for ($i = 0; $i < $strLen; $i++)
{
// Grab the next character in the string
$char = substr($json, $i, 1);
// Are we inside a quoted string?
if ('"' === $char && $noescape)
{
$outOfQuotes = !$outOfQuotes;
}
if (!$outOfQuotes)
{
$buffer .= $char;
$noescape = '\\' === $char ? !$noescape : true;
continue;
}
elseif ('' !== $buffer)
{
if ($unescapeSlashes)
{
$buffer = str_replace('\\/', '/', $buffer);
}
if ($unescapeUnicode && function_exists('mb_convert_encoding'))
{
// http://stackoverflow.com/questions/2934563/how-to-decode-unicode-escape-sequences-like-u00ed-to-proper-utf-8-encoded-cha
$buffer = preg_replace_callback('/\\\\u([0-9a-f]{4})/i',
function ($match)
{
return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
}, $buffer);
}
$result .= $buffer . $char;
$buffer = '';
continue;
}
elseif(false !== strpos(" \t\r\n", $char))
{
continue;
}
if (':' === $char)
{
// Add a space after the : character
$char .= ' ';
}
elseif (('}' === $char || ']' === $char))
{
$pos--;
$prevChar = substr($json, $i - 1, 1);
if ('{' !== $prevChar && '[' !== $prevChar)
{
// If this character is the end of an element,
// output a new line and indent the next line
$result .= $newLine;
for ($j = 0; $j < $pos; $j++)
{
$result .= $indentStr;
}
}
else
{
// Collapse empty {} and []
$result = rtrim($result) . "\n\n" . $indentStr;
}
}
$result .= $char;
// If the last character was the beginning of an element,
// output a new line and indent the next line
if (',' === $char || '{' === $char || '[' === $char)
{
$result .= $newLine;
if ('{' === $char || '[' === $char)
{
$pos++;
}
for ($j = 0; $j < $pos; $j++)
{
$result .= $indentStr;
}
}
}
// If buffer not empty after formating we have an unclosed quote
if (strlen($buffer) > 0)
{
//json is incorrectly formatted
$result = false;
}
return $result;
}