[PHP] アクセスカウンター用のRESTfulAPIを作成する - その2 DB版

前回作成した「アクセスカウンター」を、今度はデータベースに対応させてみます。裏側を変更するだけなので、表示はまったく同じです。

作戦としてはPHPにリクエストがある度にテーブルに1レコードずつ追加されていき、現在の値はレコード数を集計することでその都度算出したいと思います。毎回集計が発生するので実際の現場では使い物になりませんが、練習用としてはちょうど良いでしょう。

※この記事は専門学校の講義用に作成した物です。

DBの準備

まずはデータベース側の準備をします。

SQLを準備

以下のSQLを適当なファイル名で保存します。場所はどこでもかまいません。

/*-------------------------*/
/* データベースの準備          */
/*-------------------------*/
CREATE DATABASE access;  /* 新規にaccessという名前のDBを作成 */
USE access;              /* 利用するDBを指定 */


/*-------------------------*/
/* access_logテーブルを作成   */
/*-------------------------*/
CREATE TABLE access_log(
    id integer AUTO_INCREMENT,
    accesstime datetime,

    PRIMARY KEY(id)
);

SQLを実行する

SQLを実行するには以下の2つのパターンがありました。どちらで実行してもかまいません。

$ mysql -u (ユーザー名) -p < (SQLを保存したファイルのパス)
Enter password: (MySQL用のパスワード)
$ mysql -u (ユーザー名) -p
Enter password: (MySQL用のパスワード)

※中略

mysql>  (ここにSQL分を入力し実行する)

テーブルが作成されたか確認する

まずはデータベースがいるか確認します。「access」という名前のDBがいることがわかりますね。

$ mysql -u (ユーザー名) -p
Enter password: (MySQL用のパスワード)

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| access             |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.01 sec)

useで使用するDBを選択、show tablesでテーブルの一覧を表示、descでテーブルの詳細な情報を確認できます。

mysql> use access;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed


mysql> show tables;
+------------------+
| Tables_in_access |
+------------------+
| access_log       |
+------------------+
1 row in set (0.00 sec)


mysql> desc access_log;
+------------+----------+------+-----+---------+----------------+
| Field      | Type     | Null | Key | Default | Extra          |
+------------+----------+------+-----+---------+----------------+
| id         | int(11)  | NO   | PRI | NULL    | auto_increment |
| accesstime | datetime | YES  |     | NULL    |                |
+------------+----------+------+-----+---------+----------------+
2 rows in set (0.00 sec)

最後にexitと入力してMySQLのクライアントを終了します。

mysql> exit
Bye
$ 

ソースコード

PHP

前回作成したget.phpを以下のコードに置き換えます。DBへ接続するためのIDやパスワードなどは環境に合わせて変更してください。

<?php
/**
 * アクセスカウンターAPI (DB版)
 * 
 * @author M.Katsube <katsubemakito@gmail.com>
 * @version 1.0.0
 */

// デバッグ時にエラーを画面に表示したい場合は以下をコメントアウトする
// ini_set('display_errors', "On");

//-----------------------------------
// 定数
//-----------------------------------
define('DB_DSN',  'mysql:dbname=access;host=127.0.0.1');  // 接続先
define('DB_USER', 'senpai');    // MySQLのID
define('DB_PW',   'indocurry'); // MySQLのパスワード

//-----------------------------------
// メイン処理
//-----------------------------------
// DBに接続する
$dbh = connectDB(DB_DSN, DB_USER, DB_PW);

// DBに1レコード追加する
addCounter($dbh);

// 現在のレコード数をカウントする
$count = getCounter($dbh);

// 現在のレコード数を返却する
header('Content-type: application/json');
echo json_encode([
      'status' => true
    , 'count'  => $count
]);


/**
 * DBサーバへ接続
 * 
 * @param  string $dsn  接続先の情報(IPアドレス、DB名など)
 * @param  string $user ユーザーID
 * @param  string $pw   パスワード
 * @return object
 */
function connectDB($dsn, $user, $pw){
    $dbh = new PDO($dsn, $user, $pw);   //接続
    return($dbh);
}

/**
 * 1レコード追加する
 * 
 * @param  object $dbh
 * @return boolean
 */
function addCounter($dbh){
    // SQLを準備
    $sql = 'INSERT INTO access_log(accesstime) VALUES(now())';

    // 実行する
    $sth = $dbh->prepare($sql);   // SQLを解析
    $ret = $sth->execute();       // 実行

    return($ret);
}

/**
 * 現在のレコード数を集計する
 * 
 * @param  object $dbh
 * @return integer|boolean
 */
function getCounter($dbh){
    // SQLを準備
    $sql = 'SELECT count(*) as count FROM access_log';

    // 実行する
    $sth = $dbh->prepare($sql);    // SQLを解析
    $sth->execute();               // 実行

    // 実行結果を取得
    $buff = $sth->fetch(PDO::FETCH_ASSOC);
    if( $buff === false){
        return(false);
    }
    else{
        return( $buff['count'] );
    }
}

実行する

準備

冒頭のSQLが無事に実行し終えることができれば、あとは前回作成したget.phpの内容を置き換えるだけです。

Webブラウザから実行

前回と変わらない動きをすれば成功です。

DBを確認する

DBにMySQLのクライアントからログインし、PHPが実行される度に1レコードずつ増えていることも確認してみましょう。

$ mysql -u senpai -p
Enter password: 

mysql> use access;
mysql> select * from access_log;
+----+---------------------+
| id | accesstime          |
+----+---------------------+
|  1 | 2020-06-08 01:18:28 |
|  2 | 2020-06-08 01:18:32 |
|  3 | 2020-06-08 01:18:33 |
|  4 | 2020-06-08 01:18:37 |
|  5 | 2020-06-08 01:18:38 |
|  6 | 2020-06-08 01:18:39 |
+----+---------------------+
6 rows in set (0.00 sec)

GitHubへpushする

前回正常にpushまでできていれば、今回は差分をcommit/pushするだけです。

まずは対象のディレクトリへ移動します。

$ cd /var/www/html/counter

現在のディレクトリの状態を確認すると、「get.php」がmodifiedと表示されました。modifiedはGitの管理下にあるファイルが前回コミットがあった時点から変更があったことを表しています。

$ git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   get.php

ではget.phpをステージに登録します。

$ git add get.php

現在のステージの内容でコミットします。コメントの文字列は好きな物(日本語でもOK)を入力してください。

$ git commit -m 'file -> DB'

最後にGitHubへ送信します。ID/PWを聞かれたらGitHubのログインで利用している物を入力します。

$ git push

GitHubリポジトリのページを見て、先ほどcommitした内容が反映されていれば成功です。