PHPで簡単なアクセスカウンタを作る

目次

PHPとSQLite3が使えるレンタルサーバー用にアクセスカウンタを作ります。

作るカウンタ

作るのはアクセスがあるたびにテキストでアクセス数を表示するだけの単純な機能とします。

動作環境はPHPは"7.4.21"、カウンタ値の保存にはSQLite3を使用します。

構成

アクセスカウンタは一つのディレクトリにまとめました。

php-cgi
 └ counter
     │ .htaccess     ◀ Apache設定ファイル
     │ index.php     ◀ アクセスカウンタ表示PHPファイル
     │ CCounter.php  ◀ カウンタ値データベース操作PHPファイル
     │ counter.db    ◀ カウンタ値データベースファイル (初回実行時に自動作成)
     └

webブラウザから参照するのは"index.php"です。 CCounter.phpはデータベースを操作するプログラムですが、webブラウザからは見えないように".htaccess"で設定しています。

ソースコード

index.php

ブラウザから参照するファイルです。ここから実際にデータベースを操作する"CCounter.php"を呼び出しています。

index.php

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>アクセスカウンタ</title>
    <meta name="description" content="PHPで作ったアクセスカウンタ">
</head>
<body>
    <h1>PHPで作ったアクセスカウンタ</h1>
    <?php
        // PHPファイルを読み込みます
        require_once("CCounter.php");
        // データベースを使う準備をします
        $cnt_db = new CCounter();
        // データベースに接続します
        $cnt_db->connectDb();
        // アクセスカウンタを1加算し、値を取得します
        $count = $cnt_db->countUp();
        // データベースの後始末します
        $cnt_db->closeDb();
        // アクセスカウンタの値を文字で表示します
        echo "アクセスカウンタ:".$count;
    ?>
</body>
</html>

CCounter.php

SQLite3データベースを操作します。実行時にデータベースファイル"counter.db"が存在しない場合、カウント値を0として初期作成します。

通常時はデータベースの内容を読み込み、カウンタに1加算します。

CCounter.php

<?php
/**
 * SQLite3カウンターデータベース
 */
class CCounter {
    /**
     * データベースのインスタンス
     * 
     * @var PDO
     */
    private $db;

    /**
     * データベースファイル
     * 
     * @var string
     */
    private $db_file;

    /**
     * コンストラクタ
     * 
     * @param string $dbfile SQLite3データベースファイル
     */
    public function __construct($dbfile = 'counter.db') {
        $this->db = null;
        $this->db_file = $dbfile;
    }

    /**
     * データベースに接続する
     */
    public function connectDb() {
        // データベースファイルの存在確認
        $exist = file_exists($this->db_file);
        // PDOで接続する
        $this->db = new PDO('sqlite:'.$this->db_file, null, null, 
            [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]);
        // データベースを新規作成した場合初期設定する
        if ($exist === false) {
            $this->createTable();
        }
    }

    /**
     * データベースから切断する
     */
    public function closeDb() {
        $this->db = null;
    }

    /**
     * カウントアップしカウント数を返す
     * 
     * @return int カウント数
     */
    public function countUp() {
        // カウンタ取得SQL
        $counter_get = "SELECT counter FROM counter_tbl;";
        // カウントアップSQL
        $counter_up = "UPDATE counter_tbl SET
            counter = counter + 1,
            updated_at =  DATETIME('now');";
        // カウント数
        $count = 0;
        if ($this->db != null) {
            try {
                // カウントアップ
                $this->db->exec($counter_up);
                // カウンタ取得
                $counter_ret = $this->db->query($counter_get);
                $count = $counter_ret->fetchColumn();
            } catch (Exception $e) {
                echo '['.__LINE__.'] Exception : '.$e->getMessage();
                print_r($this->db->errorInfo());
            }
        }
        return $count;
    }

    /**
     * 新規データベースの初期設定
     */
    private function createTable() {
        // カウンタテーブル作成SQL
        $counter_table = "CREATE TABLE counter_tbl (
            counter INTEGER,
            created_at TEXT NOT NULL,
            updated_at TEXT NOT NULL
            );";
        // カウンタテーブル初期化SQL
        $counter_init = "INSERT INTO counter_tbl (
            counter, created_at, updated_at
            ) VALUES (
            0, DATETIME('now'), DATETIME('now'));";

        try {
            // テーブルを作成しカウンタの初期値を設定
            $this->db->exec($counter_table);
            $this->db->exec($counter_init);
        } catch (Exception $e) {
            echo '['.__LINE__.'] Exception : '.$e->getMessage();
            print_r($this->db->errorInfo());
        }
    }
}

.htaccess

webブラウザから参照する必要がないファイルのアクセスを制限します。

.htaccess

# ファイルをブラウザからアクセスできないように設定する
<FilesMatch "^\.htaccess|.*\.db|CCounter\.php">
  deny from all
</FilesMatch>

サーバーにアップロードする

サーバーにはさくらインターネットの「さくらのレンタルサーバ ライト」を使用します。レンタルサーバーでは"www/cgi/counter"ディレクトリに配置します。

ファイル転送には"lftp"を使用しました。

# レンタルサーバーに接続します
$ lftp -u username ftp://server.sakura.ne.jp
パスワード: [パスワードを入力]
# カレントディレクトリをアップロード先に移動します
lftp username@server.com:~> cd www/cgi
# カウンタを配置するディレクトリを作成し、移動します
lftp username@server.sakura.ne.jp:~/www/cgi> mkdir counter
mkdir 成功、`counter' を作成しました
lftp username@server.sakura.ne.jp:~/www/cgi> cd counter
cd 成功、cwd=/home/username/www/cgi/counter
# ローカルのカレントディレクトリを確認します
lftp username@server.sakura.ne.jp:~/www/cgi/counter> lpwd
/home/izumi/php-cgi/counter
# ファイルをアップロードします
lftp username@server.sakura.ne.jp:~/www/cgi/counter> put .htaccess
159 bytes transferred
lftp username@server.sakura.ne.jp:~/www/cgi/counter> put index.php
846 bytes transferred
lftp username@server.sakura.ne.jp:~/www/cgi/counter> put CCounter.php
2987 bytes transferred
# サーバのファイルを確認します
lftp username@server.sakura.ne.jp:~/www/cgi/counter> ls
drwx---r-x   2 username users         512 Sep 26 23:05 .   
drwx---r-x   4 username users         512 Sep 26 23:04 ..
-rw----r--   1 username users         159 Sep 26 22:41 .htaccess
-rw----r--   1 username users        2987 Sep 26 17:28 CCounter.php
-rw----r--   1 username users         846 Sep 26 21:37 index.php

データベースファイル"counter.db"は自動で作成するのでアップロード不要です。

サーバーで実行する

webブラウザで表示して確認します。

サーバでカウンタ実行

サーバでカウンタ実行

実行後にサーバの中身をみるとデータベースファイル"counter.db"が作成されています。

lftp username@server.sakura.ne.jp:~/www/cgi/counter> ls -a
drwx---r-x   2 username users         512 Sep 26 23:06 .      
drwx---r-x   4 username users         512 Sep 26 23:04 ..
-rw----r--   1 username users         159 Sep 26 22:41 .htaccess
-rw----r--   1 username users        2987 Sep 26 17:28 CCounter.php
-rw-r--r--   1 username users        8192 Sep 26 23:05 counter.db
-rw----r--   1 username users         846 Sep 26 21:37 index.php

カウンタページをもう一度開くとカウントは「2」になります。

サーバでカウントアップ

サーバでカウントアップ

ファイルのアクセス制御

webブラウザから見られて困るファイルは".htaccess"で制御しています。 データベースファイルのURLを指定しても拒否されます。

サーバで拒否された場合

サーバで拒否された場合

“.htaccess"を削除した場合アクセス可能となってしまうのでサーバからダウンロードされてしまいます。

サーバから見られて困るファイルをダウンロード

サーバから見られて困るファイルをダウンロード