【PHP】レンタルサーバでAPIを実装する

出典:https://hnavi.co.jp/knowledge/blog/api/

最近『API』という言葉を聞くことが多くなりましたよね。
本日はそのAPIをレンタルサーバで実装していきたいと思います。

レンタルサーバでAPIを実装するメリット・デメリット

まずはなぜレンタルサーバでAPIを実装したのか、どんな問題があったのかを、メリットとデメリットで簡単にお話しします。

メリット

料金が安い

個人でサーバを借りる場合、どうしてもコストに限界があります。

自由の高いサーバとなるとAWSやMicrosoft Azure、Google Cloud Platformなどがありますが、従量課金制で、まだまだ個人利用でハードルが高い気がします。

レンタルサーバであれば、安いもので、250円/月くらいで借りることができます。

環境構築がいらない(OS、パッケージなど)

サーバを借りて一から作る場合、OSやパッケージのインストールなどの環境構築(簡単にいうとプログラムが動く環境を作ること)は避けて通れません。

個人的にはプログラムを実装することより、環境構築の方が大変だと思っています。

レンタルサーバの場合、すでにWEBサーバが起動していたり、phpやpythonなどの言語が使えることが多く、環境構築を行う必要がありません。

デメリット

使用できるプログラミング言語が限定される

レンタルサーバは基本的にパッケージをインストールすることができません。

つまり、最初に使えるプログラミング言語以外は使用できません。

最初からWEBサーバが起動している

APIを作成する際、専用のWEBサーバを立ち上げることがほとんどだと思います。

レンタルサーバの場合、最初からWEBサーバが起動しているため、新たにWEBサーバを立ち上げることが難しい環境になっています。

PHPでAPIを実装する

さきほども言いましたが、レンタルサーバでは使用できるプログラミング言語が限られています。

今回はほとんどのレンタルサーバで使用できるPHPで簡単なAPIを実装していきます。

APIの機能

今回作成するAPIは現在の日時を取得できるAPIです。

機能は大きく分けて3つあり、日時を返す機能、日付を返す機能、時間を返す機能です。

また、エンドポイント(URL)にリクエストを送ると、Jsonがレスポンスとして返ってくるとてもシンプルなものです。

日時を返す機能

エンドポイント(GET): http://localhost:8000/v1.php/now?query=all

レスポンス:

{"date":"2018/06/25","time":"00:16:59"}

日付を返す機能

エンドポイント(GET): http://localhost:8000/v1.php/now?query=date

レスポンス:

{"date":"2018/06/25"}

日付を返す機能

エンドポイント(GET): http://localhost:8000/v1.php/now?query=date

レスポンス:

{"time":"00:16:59"}

APIを実装する

それではAPIを実装していきましょう。

まずは、現在の日時を取得し、Jsonに変換するプログラム(以後、サービスとします)を作成します。

ディレクトリ構造は以下とします。
v1.phpはルーティング(アクセスに対してどの処理を行うか)を定義します。名前をv1としているのはv2のようにバージョンアップを想定しているためです。
また、service以下には実際の処理をクラス単位で定義していきます。

├── api
    ├── service_v1
    │   └── now.php
    └── v1.php

サービスは、APIごとに1つクラスを作成し、そのクラスに必要なメソッドやプロパティを実装します。
ファイル名は必ず小文字でつけてください。

now.php

<?php

    class Now {
        // 現在の日時をjsonにして返却する関数 (引数:なし, 戻り値: json(string))
        public function getAll() {        
            // データを作成
            $jsonData = [
                "date" => (string) date("Y/m/d"),
                "time" => (string) date("H:i:s")
            ];
            // jsonに変換にしてreturn
            return json_encode($jsonData);
        }

        // 現在の日付をjsonにして返却する関数 (引数:なし, 戻り値: json(string))
        public function getDate() {
            $jsonData = [
                "date" => (string) date("Y/m/d")
            ];
            return json_encode($jsonData);
        }

        // 現在の時間をjsonにして返却する関数 (引数:なし, 戻り値: json(string))
        public function getTime() {
            $jsonData = [
                "time" => (string) date("H:i:s")
            ];
            return json_encode($jsonData);
        }
    }

?>

次にv1.phpを実装します。
アクセスしてきたURLをパースして、APIとクエリに分解します。
その後、サービスのクラスからjsonを取得し、レスポンスとして返します。

v1.php

<?php

    // エラーを表示
    ini_set('display_errors', 1);

    // now.phpをインポート
    require_once(dirname(__FILE__)."/service_v1/now.php");

    if (empty($_SERVER['PATH_INFO'])) {
        exit;
    }

    // URL内で呼ばれたAPIを$callに格納(今回はのnow)
    $parse = explode('/', $_SERVER['PATH_INFO']);
    $call = "";
    foreach ($parse as $value) {
        if ($value !== "") {
            $call = $value;
            break;
        }
    }

    // 呼ばれたAPIのクラスが存在するか確認
    if (file_exists('./service_v1/'.$call.'.php')) {
	
        // レスポンスのヘッダにjson,UTF-8,クロスオリジン対策を指定
        header("Content-Type: application/json; charset=UTF-8");
        header("X-Content-Type-Options: nosniff");
        header("Access-Control-Allow-Origin: *");
        header("Access-Control-Allow-Headers: Content-Type");

        // 呼ばれたAPIごとに処理を分ける
        switch ($call) {
            case "now":
                // クエリを取得
                $query = $_GET["query"];
                if (!(empty($query))) {
                    // レスポンス用の変数を定義
                    $response = '';
                    // nowクラス(サービス)のインスタンスを作成
                    $nowApi = new Now();
                    switch ($query) {
                        case "all":
                            $response = $nowApi->getAll();
                            break;
                        case "date":
                            $response = $nowApi->getDate();
                            break;
                        case "time":
                            $response = $nowApi->getTime();
                            break;
                        default:
                            $response = "{\"error\":\"The query is incorrect\"}";
                            break;
                    }
                    echo $response;
                }else{
                    echo "{\"error\":\"The query is not specified\"}";
                }
                break;
            default:
                break;
        }
    }

?>

以上で実装完了です。
たった2つのファイルで実装できるなんて簡単ですね。
アクセスはcurlやブラウザなどで試して見てください!

まとめ

今回はこちらの記事を参考にさせて頂きました。

実装したAPIは以下よりダウンロードできます。ご質問ご要望があればコメント下さい。

now_api.zip