我正在构建一个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”标签的使用。

希望这能帮助到别人

其他回答

我意识到这个问题是问如何编码一个关联数组到一个漂亮的JSON格式的字符串,所以这没有直接回答这个问题,但如果你有一个字符串,已经在JSON格式,你可以很简单地通过解码和重新编码它(需要PHP >= 5.4):

$json = json_encode(json_decode($json), JSON_PRETTY_PRINT);

例子:

header('Content-Type: application/json');
$json_ugly = '{"a":1,"b":2,"c":3,"d":4,"e":5}';
$json_pretty = json_encode(json_decode($json_ugly), JSON_PRETTY_PRINT);
echo $json_pretty;

这个输出:

{
    "a": 1,
    "b": 2,
    "c": 3,
    "d": 4,
    "e": 5
}

你可以在switch语句中稍微修改Kendall Hopkins的回答,通过传递一个json字符串到下面得到一个非常干净的、漂亮的缩进打印输出:

function prettyPrint( $json ){

$result = '';
$level = 0;
$in_quotes = false;
$in_escape = false;
$ends_line_level = NULL;
$json_length = strlen( $json );

for( $i = 0; $i < $json_length; $i++ ) {
    $char = $json[$i];
    $new_line_level = NULL;
    $post = "";
    if( $ends_line_level !== NULL ) {
        $new_line_level = $ends_line_level;
        $ends_line_level = NULL;
    }
    if ( $in_escape ) {
        $in_escape = false;
    } else if( $char === '"' ) {
        $in_quotes = !$in_quotes;
    } else if( ! $in_quotes ) {
        switch( $char ) {
            case '}': case ']':
                $level--;
                $ends_line_level = NULL;
                $new_line_level = $level;
                $char.="<br>";
                for($index=0;$index<$level-1;$index++){$char.="-----";}
                break;

            case '{': case '[':
                $level++;
                $char.="<br>";
                for($index=0;$index<$level;$index++){$char.="-----";}
                break;
            case ',':
                $ends_line_level = $level;
                $char.="<br>";
                for($index=0;$index<$level;$index++){$char.="-----";}
                break;

            case ':':
                $post = " ";
                break;

            case "\t": case "\n": case "\r":
                $char = "";
                $ends_line_level = $new_line_level;
                $new_line_level = NULL;
                break;
        }
    } else if ( $char === '\\' ) {
        $in_escape = true;
    }
    if( $new_line_level !== NULL ) {
        $result .= "\n".str_repeat( "\t", $new_line_level );
    }
    $result .= $char.$post;
}

echo "RESULTS ARE: <br><br>$result";
return $result;

}

现在只需运行函数prettyPrint($your_json_string);内嵌在PHP中,享受打印输出。如果你是一个极简主义者,出于某种原因不喜欢括号,你可以通过替换$char.="<br>"来轻松摆脱括号;char美元= " < br > ";在$char上的前三个开关案例中。这是你为卡尔加里市的谷歌地图API调用得到的结果

RESULTS ARE: 

{
- - - "results" : [
- - -- - - {
- - -- - -- - - "address_components" : [
- - -- - -- - -- - - {
- - -- - -- - -- - -- - - "long_name" : "Calgary"
- - -- - -- - -- - -- - - "short_name" : "Calgary"
- - -- - -- - -- - -- - - "types" : [
- - -- - -- - -- - -- - -- - - "locality"
- - -- - -- - -- - -- - -- - - "political" ]
- - -- - -- - -- - - }
- - -- - -- - -
- - -- - -- - -- - - {
- - -- - -- - -- - -- - - "long_name" : "Division No. 6"
- - -- - -- - -- - -- - - "short_name" : "Division No. 6"
- - -- - -- - -- - -- - - "types" : [
- - -- - -- - -- - -- - -- - - "administrative_area_level_2"
- - -- - -- - -- - -- - -- - - "political" ]
- - -- - -- - -- - - }
- - -- - -- - -
- - -- - -- - -- - - {
- - -- - -- - -- - -- - - "long_name" : "Alberta"
- - -- - -- - -- - -- - - "short_name" : "AB"
- - -- - -- - -- - -- - - "types" : [
- - -- - -- - -- - -- - -- - - "administrative_area_level_1"
- - -- - -- - -- - -- - -- - - "political" ]
- - -- - -- - -- - - }
- - -- - -- - -
- - -- - -- - -- - - {
- - -- - -- - -- - -- - - "long_name" : "Canada"
- - -- - -- - -- - -- - - "short_name" : "CA"
- - -- - -- - -- - -- - - "types" : [
- - -- - -- - -- - -- - -- - - "country"
- - -- - -- - -- - -- - -- - - "political" ]
- - -- - -- - -- - - }
- - -- - -- - - ]
- - -- - -
- - -- - -- - - "formatted_address" : "Calgary, AB, Canada"
- - -- - -- - - "geometry" : {
- - -- - -- - -- - - "bounds" : {
- - -- - -- - -- - -- - - "northeast" : {
- - -- - -- - -- - -- - -- - - "lat" : 51.18383
- - -- - -- - -- - -- - -- - - "lng" : -113.8769511 }
- - -- - -- - -- - -
- - -- - -- - -- - -- - - "southwest" : {
- - -- - -- - -- - -- - -- - - "lat" : 50.84240399999999
- - -- - -- - -- - -- - -- - - "lng" : -114.27136 }
- - -- - -- - -- - - }
- - -- - -- - -
- - -- - -- - -- - - "location" : {
- - -- - -- - -- - -- - - "lat" : 51.0486151
- - -- - -- - -- - -- - - "lng" : -114.0708459 }
- - -- - -- - -
- - -- - -- - -- - - "location_type" : "APPROXIMATE"
- - -- - -- - -- - - "viewport" : {
- - -- - -- - -- - -- - - "northeast" : {
- - -- - -- - -- - -- - -- - - "lat" : 51.18383
- - -- - -- - -- - -- - -- - - "lng" : -113.8769511 }
- - -- - -- - -- - -
- - -- - -- - -- - -- - - "southwest" : {
- - -- - -- - -- - -- - -- - - "lat" : 50.84240399999999
- - -- - -- - -- - -- - -- - - "lng" : -114.27136 }
- - -- - -- - -- - - }
- - -- - -- - - }
- - -- - -
- - -- - -- - - "place_id" : "ChIJ1T-EnwNwcVMROrZStrE7bSY"
- - -- - -- - - "types" : [
- - -- - -- - -- - - "locality"
- - -- - -- - -- - - "political" ]
- - -- - - }
- - - ]

- - - "status" : "OK" }

将<pre>与json_encode()和JSON_PRETTY_PRINT选项结合使用:

<pre>
    <?php
    echo json_encode($dataArray, JSON_PRETTY_PRINT);
    ?>
</pre>

递归解的经典例子。这是我的:

class JsonFormatter {
    public static function prettyPrint(&$j, $indentor = "\t", $indent = "") {
        $inString = $escaped = false;
        $result = $indent;

        if(is_string($j)) {
            $bak = $j;
            $j = str_split(trim($j, '"'));
        }

        while(count($j)) {
            $c = array_shift($j);
            if(false !== strpos("{[,]}", $c)) {
                if($inString) {
                    $result .= $c;
                } else if($c == '{' || $c == '[') {
                    $result .= $c."\n";
                    $result .= self::prettyPrint($j, $indentor, $indentor.$indent);
                    $result .= $indent.array_shift($j);
                } else if($c == '}' || $c == ']') {
                    array_unshift($j, $c);
                    $result .= "\n";
                    return $result;
                } else {
                    $result .= $c."\n".$indent;
                } 
            } else {
                $result .= $c;
                $c == '"' && !$escaped && $inString = !$inString;
                $escaped = $c == '\\' ? !$escaped : false;
            }
        }

        $j = $bak;
        return $result;
    }
}

用法:

php > require 'JsonFormatter.php';
php > $a = array('foo' => 1, 'bar' => 'This "is" bar', 'baz' => array('a' => 1, 'b' => 2, 'c' => '"3"'));
php > print_r($a);
Array
(
    [foo] => 1
    [bar] => This "is" bar
    [baz] => Array
        (
            [a] => 1
            [b] => 2
            [c] => "3"
        )

)
php > echo JsonFormatter::prettyPrint(json_encode($a));
{
    "foo":1,
    "bar":"This \"is\" bar",
    "baz":{
        "a":1,
        "b":2,
        "c":"\"3\""
    }
}

干杯

这是我自己使用的函数,api就像json_encode,除了它有第三个参数exclude_flags,以防你想排除一些默认标志(如JSON_UNESCAPED_SLASHES)

function json_encode_pretty($data, int $extra_flags = 0, int $exclude_flags = 0): string
{
    // prettiest flags for: 7.3.9
    $flags = JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE | (defined("JSON_UNESCAPED_LINE_TERMINATORS") ? JSON_UNESCAPED_LINE_TERMINATORS : 0) | JSON_PRESERVE_ZERO_FRACTION | (defined("JSON_THROW_ON_ERROR") ? JSON_THROW_ON_ERROR : 0);
    $flags = ($flags | $extra_flags) & ~ $exclude_flags;
    return (json_encode($data, $flags));
}