LoginSignup
4
4

More than 1 year has passed since last update.

PHPで超ミニマムjson-serverもどきを作る

Last updated at Posted at 2021-07-12

JSON Serverと同等の機能でPHP環境で動く物を探していたけど、結局「使う機能に絞って自分で作っちゃえ」ってなったという記事です。
さくらのレンタルサーバ ライトプラン(PHP7.4)で動作確認しました。

対象の読者

  • APIでJSONを返すモック環境を手軽に構築したい
  • PHPが動くサーバがある
  • ComposerやNode.jsを使えない

JSON Server とは

JSON ServerはAPIのモックです。
モックなので本番利用するものではありません。
公式にも、(略)who need a quick back-end for prototyping and mocking. とあります。

日本語の記事でざっと特徴を掴みたかったので、こちら↓の記事も参考にしました。

でもPHPで動かしたい

完全に環境の都合なのですが、実はAPIのモックをPHPで動かしたかったのです。
JSON ServerのPHP版といえば、PHP JSON Serverがあります。

できればcomposerなしで導入したい

さらにさらに、さくらのレンタルサーバで動かしたい事情があり、できればcomposerなしがいいんです。(その気になれば、さくらのレンタルサーバにcomposerもNode.jsも入るんですが、ここでは割愛します。)
で、いろいろ探してみたのですが「最低限のCRUDだけだし、どうせモックだし作ってみよう」ということになります。

今回作るもの

長くなりましたが今回作るjson-serverもどきを、本家との比較表で以下に示します。
ざっくり言うと、**本当にミニマムだな!**ということです。

###概要

項目 json-serverもどき 本家JSON Server
導入方法 phpと.htaccessを置くだけ npmコマンドでインストール
起動方法 (※1) npmコマンドで起動
停止方法 (※1) プロセスのkillで停止

※1:リクエストに応じてphpプロセスが立ち上がり、処理の完了とともにphpプロセスが終了するので、サーバ自体の起動・停止はありません。

###Routes(項目は本家目次から抜粋)

項目 json-serverもどき 本家JSON Server
Plural routes
Singular routes ×
Filter ×
Paginate ×
Sort ×
Slice ×
Operators ×
Full-text search ×
Relationships ×

###Extras(項目は本家目次から抜粋)

項目 json-serverもどき 本家JSON Server
Static file server "db.json"固定 オプションで可変
Alternative port phpが応答するポートのみ オプションで可変
Remote schema 同一サーバのみ オプションで可変
Add custom routes なし 設定ファイルで拡張可能
Add middlewares なし 自作Node.jsコードを組み込み可能
Module なし 自作Node.jsコードにimport可能

導入方法

サイトのDocumentRootに、後述の .htaccess と、php-json-server/php-json-server.php を配置します。
db.jsonファイルは自動的に生成されます。
(DocumentRoot以外に配置したい方は適宜修正してください。)
image.png
image.png

配置する2つのファイルは以下の通りです。

.htaccess

RewriteEngine on

RewriteCond %{REQUEST_URI} ^/root(/.*)?$
RewriteRule .* /php-json-server/php-json-server.php?path=$0 [L]

※ 上記root部分は任意の名前に変更可能です。

php-json-server.php

<?php
$path = $_GET["path"];
$path = preg_replace('/[ \/]+$/', '', $path);
$path = explode('/', $path);
$root = $path[0];
$id = $path[1] ?? "";

$filename = "db.json";
$stdin = "php://input";
$json = json_decode(file_get_contents($filename)) ?? (object) array($root => array());
$json->{$root} = $json->{$root} ?? array();
$stdin_json = json_decode(file_get_contents($stdin));

function getIndexById($elms, $id) {
  foreach($elms as $i => $elm) {
    if($elm->{"id"} == $id) {
      return $i;
    }
  }
  return -1;
}

function getById($elms, $id) {
  return $elms[getIndexById($elms, $id)] ?? (object) array();
}

function getMaxId($elms) {
  return count($elms)? max(array_map( fn($elm) => $elm->{"id"} , $elms)) : 0;
}

if($_SERVER["REQUEST_METHOD"] == "GET") {
  if($id == "") {
    print(json_encode($json->{$root}));
  } else {
    print(json_encode(getById($json->{$root}, $id)));
  }
}

if($_SERVER["REQUEST_METHOD"] == "POST") {
  $id = getMaxId($json->{$root}) + 1;
  $stdin_json->{"id"} = $id;
  array_push($json->{$root}, $stdin_json);
  file_put_contents($filename, json_encode($json));
  print(json_encode($stdin_json));
}

if($_SERVER["REQUEST_METHOD"] == "PUT") {
  $stdin_json->{"id"} = $id;
  $i = getIndexById($json->{$root}, $id);
  if($i!=-1) {
    $json->{$root}[$i] = $stdin_json;
  } else {
    array_push($json->{$root}, $stdin_json);
  }
  file_put_contents($filename, json_encode($json));
  print(json_encode($stdin_json));
}

if($_SERVER["REQUEST_METHOD"] == "DELETE") {
  $i = getIndexById($json->{$root}, $id);
  if($i!=-1) {
    array_splice($json->{$root},$i,1);
    file_put_contents($filename, json_encode($json));
  }
}

使い方

###GET
ブラウザで/rootにアクセスしてみます。
まだデータが無いので空の配列が返ってきます。
image.png

###POST
/rootへPOSTします。
image.png
再度/rootにアクセスしてみると、POSTした回数だけJSONデータが返ってきます。
idが採番されていることが分かります。
image.png

なお、/root/IDにアクセスすると、IDに該当するデータだけが表示されます。
image.png

###PUT
/root/IDへPUT。
image.png
再度/rootにアクセスしてみると、IDに該当するデータが更新されていることが分かります。
ここで、PUTで指定しなかったプロパティ(この例ではb)は消えますのでご注意ください。(本家JSON Serverも同様の挙動です。)
image.png

###DELETE
/root/IDをDELETE。
image.png
再度/rootにアクセスしてみると、IDに該当するデータが削除されていることが分かります。
image.png

まとめ

PHPでJSONをGET(全件/1件)、POST(自動採番して追加)、PUT(更新)、DELETE(1件)するAPIモックができました。
もちろん、モックですのでセキュリティも何もないのと、モックとして十分かどうかは要件次第です。

そして、本家が使える環境ならそれに越したことはないです。
(なんというか、モックだろうと名のあるものは細かいところまで本当によくできているなと改めて思いました。。。)

以上です。

4
4
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
4
4