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; }