PHPでJSON文字列を整形して出力する場合、改行やインデントを挿入しながら文字列を再構成する方法と、一度json文字列をjson_decodeでobjectに変換して整形したJSON文字列にシリアライズする方法がある。
JSON文字列を再構成して整形
public function jsonFormating($json){
$arr = str_split($json);
$ret = '';
$offset = ' ';
$arrOffset = [];
$inEscape = false;
$inStr = false;
for($i=0;$i<count($arr);$i++){
switch ($arr[$i]){
case '{' :
case '[' :
$ret .= $arr[$i];
if(!$inStr){
array_push($arrOffset,$offset);
$ret .= "\n".implode('', $arrOffset);
}
break;
case '}' :
case ']' :
if(!$inStr){
array_pop($arrOffset);
$ret .= "\n".implode('', $arrOffset);
}
$ret .= $arr[$i];
break;
case ',' :
$ret .= ",";
if(!$inStr){
$ret .= "\n".implode('', $arrOffset);
}
break;
case ':' :
if($inStr){
$ret .= ":";
}else{
$ret .= " : ";
}
break;
case '"' :
$ret .= "\"";
if(!$inStr){
$inStr = true;
}else{
if(!$inEscape){
$inStr = false;
}
}
break;
case '\\' :
if(!$inEscape) $inEscape = true;
$ret .= "\\";
break;
default :
if($inEscape) $inEscape = false;
$ret .= $arr[$i];
break;
}
}
return $ret;
}
JSON文字列をシリアライズして整形
public function jsonFormating($str){
$arrayObj = json_decode($str);
return $this->serialize($arrayObj);
}
public function serialize($data, $offset=''){
if(gettype($offset) == 'unknown type'){
$offset = "";
}
$nextoff = $offset . " ";
switch(gettype($data)){
case "string":
return '"'. $this->escapeString($data) .'"';
break;
case "integer":
case "double":
return $data;
break;
case "boolean":
return $data ? "true" : "false";
break;
case "NULL":
return "null";
break;
case "object":
$array = [];
foreach( $data as $key => $value) {
$val = $this->serialize( $value, $nextoff );
$key = '"'.$key .'"';
array_push($array, $key.":".$val);
}
if ( count($array) == 1) {
return "{ ".$array[0]." }";
}
return "{\n".$nextoff.implode($array, ",\n".$nextoff )."\n".$offset."}";
break;
case "array":
$array = [];
for ( $i=0; $i<count($data); $i++ ) {
array_push($array, $this->serialize( $data[$i], $nextoff ));
}
return "[\n".$nextoff.implode($array, ",\n".$nextoff )."\n".$offset."]";
break;
default:
return $data;
break;
}
}
private function escapeString($str){
$str = preg_replace('/\\\\/g', "\\\\\\\\", $str);
$str = preg_replace('/\"/g', "\\\"", $str);
return $str;
}