6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

JSON,ArrayをHtmlDomに変換するPHP製の変換器

Last updated at Posted at 2013-12-17

#概要
文字列型JSONや、配列を基にHtmlDomへ変換する、PHP製の変換器です。
もともとAjaxで通信する際にJSONでデータだけ通信していたものを、HtmlDomごと通信して書き換えてしまおうという魂胆で生まれました。
JSONは本来軽量なデータ記述言語ですが、ガン無視ですw
でもこれでjavascript側でデータを受け取ってウェブページに反映するという作業ではなく、書き換え部分を全て消してから挿入するという方法が取れる様になります。
(Ajaxではないですね、、、多分これを使うタイミングはgoogle検索のようなGETで受け取った内容を基にリロードする際にArrayを受け取って変更箇所にDomベタ書きっていう感じ)

(HtmlDomからJSON,Arrayへの変換は使わないのでまだ未実装ですが、時間があればやってみたいかなと・・・)

##同じことをするJavaScript製の変換器も作りました
Qiita.com:JSON,ArrayをHtmlDomに変換するJavaScript製の変換器

##注意
この処理にはjson_decodeや無名関数の再帰を行っています。
そのため、再帰回数の制限(環境によりけりの多次元配列の階層制限100~)を超えるような場合は結果がNULLになり得ます。
PHP:PHP: json_decode - Manual

#コード
長いですが上数十行が本体で、それ以下は文字列JSONや、Arrayなどのテストデータとなっています。
簡単に実行できるので、そのままコピーして以下のようにしてください。

php ./Decoder.php
Decoder.php
<?php

	class Decoder {

		function getJsonToHtmlString($jsondata_string) {
			return $this -> getArrayToHtmlString(json_decode($jsondata_string, TRUE));
		}

		function getArrayToHtmlString($arraydata_array) {
			/*
			 * $createDomDomelement($dom_array)
			 *
			 * dom_arrayから、element, attribute, textを基にdomを生成、
			 * childrenが存在している場合再帰させ、dhildren要素を作成後にdomへ子要素として追加
			 */
			$getDomDomelement = function($dom_array, $root_domdocument) use (&$getDomDomelement) {
				$domelement_domelement = NULL;

				if (isset($dom_array['element'])) {
					if (isset($dom_array['text']))
						$domelement_domelement = $root_domdocument -> createElement($dom_array['element'], $dom_array['text']);
					else
						$domelement_domelement = $root_domdocument -> createElement($dom_array['element']);

					if (isset($dom_array['attribute'])) {
						foreach ($dom_array['attribute'] as $attributekey_string => $attributevalue_string) {
							$domattr_domdocument = $root_domdocument -> createAttribute($attributekey_string);
							$domattr_domdocument -> value = $attributevalue_string;

							$domelement_domelement -> appendChild($domattr_domdocument);
						}
					}

					if (isset($dom_array['children'])) {
						foreach ($dom_array['children'] as $childrendom_array)
							$domelement_domelement -> appendChild($getDomDomelement($childrendom_array, $root_domdocument));
					}
				}

				if (isset($domelement_domelement))
					$root_domdocument -> appendChild($domelement_domelement);

				return $domelement_domelement;
			};

			$main = function($arraydata_array) use ($getDomDomelement) {
				$root_domdocument = new DOMDocument();

				if (is_array($arraydata_array))
					foreach ($arraydata_array as $value) {
						if (isset($value['element'])) {
							$root_domdocument -> appendChild($getDomDomelement($value, $root_domdocument));
						}
					}

				return $root_domdocument;
			};

			return $main($arraydata_array) -> saveHTML();
			;
		}

	}

	// @formatter:off
	$jsondata_string = '
[
	{
		"element":"div",
		"attribute":{
			"id":"top",
			"class":"text"
		},
		"children":[
			{
				"element":"div",
				"attribute":{
					"class":"text",
					"data-test_data":"test data !"
				},
				"children":[
					{
						"element":"p",
						"text":"No.",
						"children":[
							{
								"element":"b",
								"text":"1"
							}
						]
					}
				]
			},{
				"element":"div",
				"attribute":{
					"class":"text",
					"data-test_data":"test data !!"
				},
				"children":[
					{
						"element":"p",
						"text":"No.",
						"children":[
							{
								"element":"b",
								"text":"2"
							}
						]
					}
				]
			},{
				"element":"div",
				"attribute":{
					"class":"text",
					"data-test_data":"test data !!!"
				},
				"children":[
					{
						"element":"p",
						"text":"No.",
						"children":[
							{
								"element":"b",
								"text":"3"
							}
						]
					}
				]
			}
		]
	},
	{
		"element":"p",
		"attribute":{
			"id":"end"
		},
		"text":"JSON TO HTML SAMPLE"
	}
]';

	$arraydata_array = array(
		array(
			"element" => "div",
			"attribute" => array(
				"id" => "top",
				"class" => "text"
			),
			"children" => array(
				array(
					"element" => "div",
					"attribute" => array(
						"class" => "text",
						"data-test_data" => "test data !"
					),
					"children" => array(
						array(
							"element" => "p",
							"text" => "No.",
							"children" => array(
								array(
									"element" => "b",
									"text" => "1"
								)
							)
						)
					)
				),array(
					"element" => "div",
					"attribute" => array(
						"class" => "text",
						"data-test_data" => "test data !!"
					),
					"children" => array(
						array(
							"element" => "p",
							"text" => "No.",
							"children" => array(
								array(
									"element" => "b",
									"text" => "2"
								)
							)
						)
					)
				),array(
					"element" => "div",
					"attribute" => array(
						"class" => "text",
						"data-test_data" => "test data !!!"
					),
					"children" => array(
						array(
							"element" => "p",
							"text" => "No.",
							"children" => array(
								array(
									"element" => "b",
									"text" => "3"
								)
							)
						)
					)
				)
			)
		),array(
			"element" => "p",
			"attribute" => array(
				"id" => "end"
			),
			"text" => "JSON TO HTML SAMPLE"
		)
	);
	// @formatter:on

	$decoder = new Decoder();
	echo $decoder -> getJsonToHtmlString($jsondata_string);

	echo "\n\n----\n\n";

	echo $decoder -> getArrayToHtmlString($arraydata_array);
?>

##実行結果

<div id="top" class="text">
	<div class="text" data-test_data="test data !">
		<p>No.<b>1</b></p>
	</div>
	<div class="text" data-test_data="test data !!">
		<p>No.<b>2</b></p>
	</div>
	<div class="text" data-test_data="test data !!!">
		<p>No.<b>3</b></p>
	</div>
</div><p id="end">JSON TO HTML SAMPLE</p>
6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?