2012-11-15 39 views
2

这个php脚本将一个元素添加到其中一个JSON对象(数组)。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,这意味着我不能使用PHP 5.4,其具有编码“PRETTY_PRINT”选项。

有没有办法(让我的文件结构在PHP 5.3.10使用json_encode);?

回答

2

使用print_r

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

意识到,正是你需要的JSON文件,检查this function

+1

对不起,指出显而易见的,但'print_r()'不会产生JSON。 –

+0

该功能似乎没问题,但它似乎在引号内跳出斜杠。这是正确的行为? – Tool

+0

你可以自定义 –

1

遗憾的是没有。

由于数据是用于机消费这不应该是一个主要的问题 - 如果你要目视检查它,有一些工具,你会根据上下文自动做漂亮的印刷。

+0

是否有一个CLI/PHP工具格式化JSON文件很好?我可以在添加元素后在文件上运行该命令。 – Tool

0

用于通过丹尼斯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 ...