前提
クライアントではJavaScriptを、サーバーではPHPを使用しているものとします。
結論から言うと・・・
早見にするとこんな感じ
「JSONにする」は「JSON形式の文字列に変換する」、
「JSONから戻す」は「JSON形式の文字列をもとの値に変換する」を言い換えています。
クライアント(JavaScript)側
- なんらかの値をJSON形式の文字列に変換
// 変数fooの値をJSON形式の文字列に変換する。 var bar = JSON.stringify(foo);
- JSON形式の文字列を値に変換
// 変数fooは、JSON形式の文字列。 var bar = JSON.parse(foo);
サーバー(PHP)側
- なんらかの値をJSON形式の文字列に変換
// 変数$fooの値をJSON形式の文字列に変換する。 $bar = json_encode($foo);
- JSON形式の文字列を値に変換
// 変数$fooは、JSON形式の文字列を格納した変数。 $bar1 = json_decode($foo); // 連想配列形式にしたい場合は第2引数に'true'を指定する。 $bar2 = json_decode($foo, true);
処理の流れ
実際には以下のような順番になるでしょう。
- クライアントからサーバーへ
- クライアント(JavaScript)でJSON.stringify()を実行
- サーバーへ送信
- サーバー(PHP)でjson_decode()を実行
- サーバーからクライアントへ
- サーバー(PHP)でjson_encode()を実行
- クライアントへ送信/HTMLへ埋め込む
- クライアント(JavaScript)でJSON.parse()を実行
もう少し詳しく
JSONとは
JSONは"JavaScript Object Notation"の略で、複数の言語間で共通して値を扱うためのフォーマットです。
たとえばJavaScript上で作成した配列をJSON形式の文字列に変換し、PHP上で配列に戻して使用するといったことが可能になります。
詳しくはjson.orgのサイトやWikipediaの解説が参考になります。
基本的には、「キー」と「値」の組み合わせを文字列として表現していると考えればよいかと思います。
[PHP]json_decode()の第2引数について
json_decode()がエラーとなるケースについても書いてあるので、以下のドキュメントは一読されることをお勧めします。
さて、上のドキュメントにある通りですが、JSON形式の文字列をPHPの値に変換するとき、連想配列の形式にしたい場合には第2引数を「true」にしてやる必要があります。
たとえば変換元となるJSON形式の文字列がもともとは連想配列の場合、第2引数を指定せずにjson_decode()を実行すると値はオブジェクト型になります。
これを連想配列にするには第2引数に「true」を指定します。
オブジェクトなのか? 連想配列なのか? によって値の取得方法等は異なってきますので注意が必要です。
$foo = array( "key_1" => "val_1", "key_2" => "val_2", ); // $bar1はオブジェクト型 $bar1 = json_decode($foo); // オブジェクトのメンバにアクセスするので「->」を用いて値を取得する。 $val = $bar1->key_1; // $bar2は連想配列型 $bar2 = json_decode($foo, true); // 連想配列の値にアクセスするのでキー名を指定して値を取得する。 $val = $bar2['val_1'];
[jQuery]data()関数使用時の動きについて
DOMのdata属性にJSON形式の文字列を保持しておく場合を考えます。
これをdata()関数を使って取得すると、JSON形式の文字列から元の値へと暗黙的に変換されます。(JSON.parse()を実行するのと同等)
When the data attribute is an object (starts with '{') or array (starts with '[') then
jQuery.parseJSON
is used to parse the string; it must follow valid JSON syntax including quoted property names. If the value isn't parseable as a JavaScript value, it is left as a string..data() | jQuery API Documentation
この挙動は便利ですが注意が必要な場合もあります。
JSON形式の文字列をそのまま送信したい場合です。
以下のように書くと、どのようなパラメータが送信されるでしょうか?
var foo = { "key_1": "val_1", "key_2": "val_2", }; // idが「bar」である要素の「data-json_str」属性にfooをセット。 $("#bar").data("json_str", foo); // 適当なURLに対し、JSON形式の文字列をパラメータにして送信したい。 $.ajax({ method: "POST", url: "適当なURL", data: { "json_str": $("#bar").data("json_str")}, });
json_str: {"key_1": "val_1", "key_2": "val_2"}
とはなりません。上のようにJSON形式の文字列として送信されるのではなく、
json_str[key_1]: "val_1" json_str[key_2]: "val_2"
というように、キーと値に展開した形で送信されます。
サーバー側でJSON形式の文字列を受け取るつもりでいると、意図しない形式の値を扱うことになってしまいます。
JSON形式の文字列として送信するには、
$("#bar").data("json_str", JSON.stringify(foo));
上のように文字列化してからdata属性にセットしておくとよいでしょう。
関数名の語源から考える
正直言って、よく忘れます!
どちらが文字列に変換する関数で、どちらが値に復元する関数だったのか?
関数名の語源を考えると、イメージしやすくなる気がします。
以下、weblioの回し者みたいにリンクを貼りまくっています。
辞書を横断して用例等が記載されていますので、気になる方はリンク先も確認してみてください。
JSON.stringify()
"stringify"という語は「文字列」を表す"string"と、接尾辞"-fy"に分解できます。
"-fy"という接尾辞には「~にする」という意味があります。
"stringify"は「文字列化する」という意味になります。
JavaScript上の値をJSONというフォーマットに従って「文字列化する」わけですね。
JSON.parse()
"parse"には「解析する」という意味があります。
JSON形式の文字列を解析して、JavaScript上の値に戻してあげるイメージでしょうか。
json_encode()
"code"には「暗号」、「ある内容を一定の規則に従ってあらわしたもの」という意味があります。
"en-"は「~にする」という意味の接頭辞です。
JSON.stringify()と同様、JSONというフォーマットに従った文字列に変換するというイメージです。
json_decode()
"de-"は「否定」や「逆転」の意味を持つ接頭辞です。
また"decode"には「暗号を平文にする」という意味があります。
JSON形式の文字列にされたものを、もとの値に戻してやる感じですね。
終わりに
今回は以上です。
ご意見やご感想等はコメントまで願いします。
Enjoy coding!
更新履歴
- 2018/07/01 初版作成
- 2018/07/03 早見追加
コメント