JSON解码/编码丢失换行符/文件结构?

时间:2012-11-15 11:01:26

标签: php json

这个php脚本为其中一个JSON对象(数组)添加了一个元素。

#!/usr/bin/php
<?php

$filename = 'composer.json';
$obj = json_decode(file_get_contents($filename, true));

if (null === $obj) {
   throw new Exception(json_last_error()); // this will just be an error code
}

$obj->require = (object) array_merge((array) $obj->require, array('friendsofsymfony/user-bundle' => "*"));

file_put_contents(
    $filename,
    json_encode($obj)
);

问题是,它弄乱了文件格式。

在使用脚本之前,我正在编辑的文件如下所示:

{
    "name": "symfony/framework-standard-edition",
    "description": "The \"Symfony Standard Edition\" distribution",
    "autoload": {
        "psr-0": { "": "src/" }
    },
    "require": {
        "php": ">=5.3.3",
        "symfony/symfony": "2.1.*",
        "doctrine/orm": ">=2.2.3,<2.4-dev",
        "doctrine/doctrine-bundle": "1.0.*",
        "twig/extensions": "1.0.*",
        "symfony/assetic-bundle": "2.1.*",
        "symfony/swiftmailer-bundle": "2.1.*",
        "symfony/monolog-bundle": "2.1.*",
        "sensio/distribution-bundle": "2.1.*",
        "sensio/framework-extra-bundle": "2.1.*",
        "sensio/generator-bundle": "2.1.*",
        "jms/security-extra-bundle": "1.2.*",
        "jms/di-extra-bundle": "1.1.*"
    },
    "scripts": {
        "post-install-cmd": [
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
        ],
        "post-update-cmd": [
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets",
            "Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"
        ]
    },
    "minimum-stability": "dev",
    "extra": {
        "symfony-app-dir": "app",
        "symfony-web-dir": "web"
    }
}

运行脚本后;我明白了:

{"name":"symfony\/framework-standard-edition","description":"The \"Symfony Standard Edition\" distribution","autoload":{"psr-0":{"_empty_":"src\/"}},"require":{"php":">=5.3.3","symfony\/symfony":"2.1.*","doctrine\/orm":">=2.2.3,<2.4-dev","doctrine\/doctrine-bundle":"1.0.*","twig\/extensions":"1.0.*","symfony\/assetic-bundle":"2.1.*","symfony\/swiftmailer-bundle":"2.1.*","symfony\/monolog-bundle":"2.1.*","sensio\/distribution-bundle":"2.1.*","sensio\/framework-extra-bundle":"2.1.*","sensio\/generator-bundle":"2.1.*","jms\/security-extra-bundle":"1.2.*","jms\/di-extra-bundle":"1.1.*","friendsofsymfony\/user-bundle":"*"},"scripts":{"post-install-cmd":["Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap","Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache","Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets","Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"],"post-update-cmd":["Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::buildBootstrap","Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::clearCache","Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installAssets","Sensio\\Bundle\\DistributionBundle\\Composer\\ScriptHandler::installRequirementsFile"]},"minimum-stability":"dev","extra":{"symfony-app-dir":"app","symfony-web-dir":"web"}}

所有新行等都将丢失。

我的PHP版本是5.3.10,这意味着我不能使用具有“PRETTY_PRINT”选项进行编码的PHP 5.4。

有没有办法使用json_encode()保留我在PHP 5.3.10中的文件结构??

4 个答案:

答案 0 :(得分:2)

使用print_r

$pretty_json = print_r(json_decode($arr, true), true);

意识到您需要准确的json文件,请检查this function

答案 1 :(得分:1)

不幸的是没有。

由于数据是用于机器消耗的,因此这不应该是一个主要问题 - 如果您想要进行视觉检查,有许多工具可以根据上下文自动为您自动打印。

答案 2 :(得分:0)

为什么格式很重要?当然,这是为了一个程序/过程消耗,消除人类可读性的需要?

我有一个方便的谷歌浏览器扩展程序用于查看json提要:

https://chrome.google.com/webstore/detail/json-formatter/bcjindcccaagfpapjjmafapmmgkkhgoa

答案 3 :(得分:0)

使用Denis Ermolin提供的function,并添加了str_replace():

<?php

$filename = 'composer.json';
$obj = json_decode(file_get_contents($filename, true));

if (null === $obj) {
   throw new Exception(json_last_error()); // this will just be an error code
}

$obj->require = (object) array_merge((array) $obj->require, array('friendsofsymfony/user-bundle' => "*"));

file_put_contents($filename,pretty_json(json_encode($obj)));

function pretty_json($json) {
    $result      = '';
    $pos         = 0;
    $strLen      = strlen($json);
    $indentStr   = '  ';
    $newLine     = "\n";
    $prevChar    = '';
    $outOfQuotes = 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 == '"' && $prevChar != '\\') {
            $outOfQuotes = !$outOfQuotes;
        // If this character is the end of an element, 
        // output a new line and indent the next line.
        } else if(($char == '}' || $char == ']') && $outOfQuotes) {
            $result .= $newLine;
            $pos --;
            for ($j=0; $j<$pos; $j++) {
                $result .= $indentStr;
            }
        }
        // Add the character to the result string.
        $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 == '[') && $outOfQuotes) {
            $result .= $newLine;
            if ($char == '{' || $char == '[') {
                $pos ++;
            }
            for ($j = 0; $j < $pos; $j++) {
                $result .= $indentStr;
            }
        }
        $prevChar = $char;
    }
    $result = str_replace("\\/", "/", $result);
    return $result;
}
?>

或者只是更新到PHP 5.4以使用PRETTY_PRINT ...