兵どもが、夢のあとさき

JavaScript 系の言語に興味を惹かれ、まったりと更新しております

JSONあれこれ(1)

JSON 形式のデータを返す

 これまでどちらかと言えば XML に縁があったのですが、JSON形式のデータはXML等に比べて軽量で、かつ javascript との相性も良いのでこれから積極的に使用していきたいと考えています。(難を言えば、名称が某スプラッタ映画を…)

 以下は、翔泳社から発行されている『PHP 逆引きレシピ 第2版』のレシピを参考に勉強した内容をつらつら書き連ねたものです。最終的には、「(DBなどから)データ取得」→「JSONエンコード」→「送受信」→「JSONデコード」→「結果を表示」の一連の流れを記載できたら良いなと。また、「JSONデコード」と「結果を表示」は親和性の良い jQuery を使用します。

 

JSON形式のデータを返すWeb APIを作りたい
<?php
# jQueryなど主要なJavaScriptライブラリを通じてのアクセスである
# (ブラウザからの直接アクセスでない)ことを確認します。
# この方法はJSONハイジャック攻撃など☆レシピ305☆(JSONのセキュリティについて知りたい)に対しても有効です。
if (! isset($_SERVER['HTTP_X_REQUESTED_WITH']) ||
    $_SERVER['HTTP_X_REQUESTED_WITH'] !== 'XMLHttpRequest') {
  die(json_encode(array('status' => "不正な呼び出しです")));
}

# データを準備します。
$value = array(
  1 => array('item' => '台湾ラーメン', 'price' => 580, 'orders' => 113),
  2 => array('item' => '台湾ラーメン(アメリカン)', 'price' => 580, 'orders' => 72),
  3 => array('item' => 'ニンニクチャーハン', 'price' => 630, 'orders' => 87),
);

# Content-Typeを「application/json」に設定します。
header("Content-Type: application/json; charset=UTF-8");
# Internet ExplorerがContent-Typeヘッダーを無視しないようにします☆レシピ287☆(XSS対策をしたい)。
header("X-Content-Type-Options: nosniff");

# 可能な限りのエスケープを行ない、JSON形式で結果を返します。
echo json_encode(
  $value,
  JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP
);
/* ?>終了タグ省略 ☆レシピ001☆(サーバーのPHP情報を知りたい) */

 

のっけから空腹を刺激するJSONデータです。本来は、このデータをDBなどから取得したりします。とりあえず、セキュリティに関する件は後回しにして、最後の json_encode メソッドですが、これが $value 値を JSON 形式の文字列に変換します。

json_encode の挙動を確認するために、上記のレシピをコマンドラインで実行するために少し端折ります。

<?php
# データを準備します。
$value = array(
  1 => array('item' => '台湾ラーメン', 'price' => 580, 'orders' => 113),
  2 => array('item' => '台湾ラーメン(アメリカン)', 'price' => 580, 'orders' => 72),
  3 => array('item' => 'ニンニクチャーハン', 'price' => 630, 'orders' => 87),
);

# 可能な限りのエスケープを行ない、JSON形式で結果を返します。
echo json_encode(
  $value,
  JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP
);

上記の結果は、以下のようになります。(台湾ラーメンUnicode値がエスケープされた値になります)

{"1":{"item":"\u53f0\u6e7e\u30e9\u30fc\u30e1\u30f3","price":580,"orders":113},"2 ":{"item":"\u53f0\u6e7e\u30e9\u30fc\u30e1\u30f3(\u30a2\u30e1\u30ea\u30ab\u30f3)" ,"price":580,"orders":72},"3":{"item":"\u30cb\u30f3\u30cb\u30af\u30c1\u30e3\u30f c\u30cf\u30f3","price":630,"orders":87}}

 これじゃ読めんという方は、JSON_UNESCAPED_UNICODE パラメータを付加することで

# 可能な限りのエスケープを行ない、JSON形式で結果を返します。
echo json_encode(
  $value,
  JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_UNESCAPED_UNICODE
);  

 下記の様に、Unicode値のまま表示されます。(PHP >= 5.4.0)

{"1":{"item":"台湾ラーメン","price":580,"orders":113},"2":{"item":"台湾ラーメン(アメリカン)","price":580,"orders":72},"3":{"item":"ニンニクチャーハン","price":630,"orders":87}}

 とりあえず、JSONを出力するプログラムができました。これを json.php で保存し、Webサーバの設定を行い、http://localhost/php-recipe/07/11/json.php でアクセスできるようにしておきます。