カウンター

概要

それではMVCの仕組みを利用して何か作ってみます。
実践編のところと内容がかぶりますが、トップページにカウンターを組み込む例です。

仕組み的に、URLでアクションが指定されていない場合は"index"アクション、つまりコントローラークラスの"indexAction()"メソッドが呼び出されます。

更にコントローラーの指定もない場合は"index"コントローラー、つまり"IndexController"クラスがコントローラークラスとなります。

通常、URLでドメイン以下の指定がない場合はindex.html、つまりトップページが表示されると思います。
それにあわせた動きになるように、IndexControllerのindexActionはトップページのスクリプトということになります。


尚、趣旨がMVC実装なので、説明簡略化の為、今回のカウンターは単純にアクセスがあるたびに加算されていく、超単純なカウンターとします。

ディレクトリ構成は「準備」のでご紹介したものに従います。

モデルクラス

モデルクラスを作ります。
今回はモデルとテーブルを関連付けて、モデルをテーブルオブジェクトとして扱います。

sample/models/Counter.php
<?php

class Counter extends ModelBase
{
    // カウンター値取得
    public function getCounterCount()
    {
        $sql = sprintf(
            "SELECT IFNULL(visit_count, 0) AS visit_count FROM %s WHERE date = :date",
            $this->name
        );
        $params = array('date' => date('Ymd'));
        $rows = $this->query($sql);
        $row = $rows[0];
        return $row['visit_count'];
    }
    
    // カウンター加算処理
    public function increment()
    {
        // 本日の日付のレコードが存在するか確認
        $sql = sprintf(
            "SELECT COUNT(*) AS cnt FROM %s  WHERE date = :date",
            $this->name
        );
        $params = array('date' => date('Ymd'));
        $rows = $this->query($sql);
        $row = $rows[0];
        
        $res = false;
        
        // なければINSERT、あればUPDATE
        if ($row['cnt'] == 0) {
            $sql = sprintf(
                "INSERT INTO %s (date, visit_count) VALUES ('%s', 1)",
                $this->name,
                date('Ymd')
            );
            $res = $this->db->exec($sql);
        } else {
            $sql = sprintf(
                "UPDATE %s SET visit_count = visit_count + 1 WHERE date = '%s'",
                $this->name,
                date('Ymd')
            );
            $res = $this->db->exec($sql);
        }
        return $res;
    }
}

?>

"counter"というテーブルが存在する前提です。
このテーブルには単純に日付とそれに対するカウンター値が保存されているだけの単純な構造です。

処理としては、単にカウンターを加算する処理と、本日のカウンター値を取得する機能だけです。

コントローラークラス

今度はコントローラークラスです。

sample/controllers/IndexController.php
<?php

class IndexController extends ControllerBase
{
    public function indexAction()
    {
        $counter = new Counter();
        // カウンターを加算
        $counter->increment();
        // カウンター値取得
        $cnt = $counter->getCounterCount();
        
        // テンプレートに出力
        $this->view->assign('counter', $cnt);
    }
}

?>

カウンターのモデルを利用してカウンターの加算と加算後のカウンター値を取得しているだけです。

ビューテンプレート

最後にテンプレートです。

sample/views/index/index.tpl
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>トップページ</title>
</head>
<body>

<p>あなたは{$counter}番目の訪問者です</p>

</body>
</html>

以上のように、MVCの仕組みが出来上がっていれば、
基本的に機能実装はコントローラークラス、モデルクラス、ビューテンプレートをセットで作るような形になります。
処理ロジックはモデル、デザインはテンプレート、そしてその橋渡し的役割を果たすのがコントローラーです。

機能追加時は常にこのパターンに沿って作ればいいわけです。