PHPでJSONデータを返すWebAPIを作る機会があったので記しておく。
PHPのバージョンは5.4である。
PHPでJSONデータを作るには、対応する連想配列を作成し、関数 json_encode() でエンコードする。
要求元に送信するには、header()関数で “Content-Type: application/json; charset=UTF-8” を送信した後にecho()でエンコードしたデータを投げる。
次の例は指定した日付の出荷商品リストをデータベースから取得しJSONで返すプログラムである。なお、データベースはPostgreSQLを使用しているが、MySQLやOracle等に置き換えることも可能。
<?php
#定数
define('PG_CONNECT_STRING', 'host=localhost port=5432 dbname=mydb user=oreore password=orenopass');
## パラメータの取得
if (!isset($_GET['syudate'])) {
http_response_code(500); //HTTPレスポンスコード(500サーバーエラー)
echo "no syudate parameter";
exit();
}
$paramsyudate = $_GET['syudate'];
## 出荷日のチェック
# 桁数のチェック
if (strlen($paramsyudate)!=8) {
http_response_code(500);
echo "syudate length is not 8";
exit();
}
# YYYYMMDD形式のチェック
$stryear = substr($paramsyudate, 0, 4);
$strmonth = substr($paramsyudate, 4, 2);
$strday = substr($paramsyudate, 6, 2);
if (!checkdate($strmonth, $strday, $stryear)) {
http_response_code(500);
echo "syudate is not date";
exit();
}
#JSONデータの雛形(連想配列)
$json = array(
'syudate' => $paramsyudate,
'syukkalist' => array()
);
# SQL作成
$sql = "SELECT syudate, itemcode, itemname\n";
$sql .= "FROM syukkatable WHERE syudate = " . $paramsyudate . ";";
#PostgeSQLに接続
$pgconn = pg_connect(PG_CONNECT_STRING);
if (!$pgconn) {
http_response_code(500);
echo "cannot connect PostgreSQL";
exit();
}
#レコードセット取得
$result = pg_exec($pgconn, $sql);
$syukkalist = array(); //出荷リスト保存用配列
while ($fields = pg_fetch_array($result)) {
#送信データ(1行)の作成(連想配列)
#キャストしてデータ型を指定すると良い
$syukkadata = array(
'itemcode' => (string)$fields['itemcode'] ,
'itemname' => (string)$fields['itemname']
);
#出荷リストに追加
array_push($syukkalist, $syukkadata);
}
pg_close($pgconn); //DB接続切断
$json['syukkalist'] = $syukkalist; //出荷リストをJSONに登録
http_response_code(200); //HTTPレスポンスコード(200正常終了)
header('Content-Type: application/json; charset=UTF-8');
header("X-Content-Type-Options: nosniff");
echo json_encode($json, JSON_UNESCAPED_UNICODE); //エンコードして送信
exit();
?>
このPHPのファイル名を「getsyukkalist.php」とすると
http://hogehoge.com/getsyukkalist.php?syudate=20180901
という具合に西暦8桁の日付を変数syudateの値にしてリクエストしたら、以下のようなJSONデータが返ってくる。
{
"syudate": "20180901",
"syukkodatas": [
{
"itemcode": "code001",
"itemname": "商品001"
},
{
"itemcode": "code002",
"itemname": "商品002"
}
]
}
json_encode()の第二引数にJSON_UNESCAPED_UNICODEを指定しておかないと日本語などのマルチバイト文字がバックスラッシュでエスケープされた文字コードに変換されてしまうのでそこだけは注意。
それからPHPは変数のデータ型が曖昧なのでJSONに変換したとき、数値が文字列として扱われたり、その逆になることがある。なので元データの連想配列を作るときは(int)や(string)でキャストしてデータ型を指定すると良い。