PHPでJSONの整形


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