準備

ディレクトリ構成

まずはディレクトリ構成です。

(ROOT)/
  ∟library/
    ∟mvc/
      ∟ControllerBase.php
      ∟Dispatcher.php
      ∟ModelBase.php
      ∟Post.php
      ∟QueryString.php
      ∟Request.php
      ∟UrlParameter.php
      ∟Smarty/
  ∟public_html/
    ∟sample/
        ∟controllers/
          (コントローラークラス配置)
        ∟models/
          (モデルクラス配置)
        ∟views/
          ∟templates/
              (ビューテンプレート配置)
          ∟templates_c/
        ∟htdocs/
          ∟css/
          ∟images/
          ∟js/
          ∟.htaccess
          ∟index.php

libraryというディレクトリをつくり、共通ライブラリクラス等をそこに置くことにします。
そのなかでMVCに関わる物はmvcというディレクトリを作り、その中に入れておくことにします。

次に今回のサンプルのシステムを動かす環境としてsampleというディレクトリを作ります。
で、controllers、models、views、htdocsをその中につくり、apacheの設定としてはこのhtdocsがドキュメントルートになるように設定します。

更に.htaccessでリライト設定も行います。

リライト設定

まずは public_html/sample/htdocs のディレクトリがドキュメントルートとなるようにapacheの設定を行います。

httpd.conf
<VirtualHost *>
    DocumentRoot /home/www/public_html/sample/htdocs
    ServerName www.xxxx.com
    ErrorLog logs/sample_error_log
    CustomLog logs/sample_custom_log common
</VirtualHost>

ちなみにこの設定は自宅サーバーなど、apacheの設定が直接変更できる環境にある場合しか設定できません。
レンタルサーバーなどの場合でどうやってもドキュメントルートの設定が変更できない場合は、htdocs以下のファイルやディレクトリを所定のドキュメントルート直下におくしかありません。


次にリライト設定です。
リライト設定は.htaccessに記述します。

.htaccess
Options +FollowSymLinks
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule !\.(pdf|ico|gif|jpg|png|css|html|xml)$ index.php

mod_rewriteの設定の仕方の詳細は詳しいサイトがたくさんあるのでググってみてください。

簡単に言うと上記の設定だと、URLで指定されたディレクトリやファイルが実際には存在しない場合のみリライトが働くようになります。
そしてURLで直接、pdf、ico、gif、jpg、png、css、html、xmlのいずれかの拡張のファイルが指定された場合はリライトが働きません。

それ以外の場合はすべてindex.phpへ強制的に転送されます。

RewriteBaseという部分がありますが、
例えばapacheのドキュメントルートの設定がpublic_htmlになっている状態で、
pulic_html/sample/htdocsの中にindex.phpが存在する場合だと、
.htaccessのRewriteBaseの部分は

RewriteBase /sample/htdocs

とする必要があります。

index.phpでのシステム共通設定

リライト設定により、サイトに対する全てのアクセスは、いったんindex.phpに入ります。

index.phpには、URLに対応するクラスへの処理を振り分けることの他に、サイト共通の初期設定という重要な役割が存在します。

index.php
<?php

// システムのルートディレクトリパス
define('ROOT_PATH', realpath(dirname(__FILE__) . '/..'));
// ライブラリのディレクトリパス
define('LIB_PATH', realpath(dirname(__FILE__) . '/../../library'));

// ライブラリとモデルのディレクトリをinclude_pathに追加
$includes = array(LIB_PATH . '/mvc', ROOT_PATH . '/models');
$incPath = implode(PATH_SEPARATOR, $includes);
set_include_path(get_include_path() . PATH_SEPARATOR . $incPath);

// クラスのオートロード
function __autoload($className){
    require_once $className . ".php";
}

// データベース接続情報設定
$connInfo = array(
    'host'     => 'localhost',
    'dbname'   => 'sample',
    'dbuser'   => 'hoge',
    'password' => 'xxxxxxxx'
);
ModelBase::setConnectionInfo($connInfo);

// リクエスト処理
$dispatcher = new Dispatcher();
$dispatcher->setSystemRoot(ROOT_PATH);
$dispatcher->dispatch();


?>

まず、サイトのシステムの存在するディレクトリと、共通ライブラリのディレクトリの絶対パスを定数として定義しています。

次にライブラリやモデルなどの、都度呼び出されるクラスの格納されているディレクトリをinclude_pathに追加します。
ライブラリは共通に利用するものですので、php.iniに直接設定してもかまいません。

そしてinclude_pathに設定されたディレクトリ内に存在するクラスは、
いちいちrequire_onceなどで読み込まないでもいいようにオートロード関数を定義しておきます。
__autoload関数はPHPの標準関数で、未定義のクラスを使おうとした時に自動的に呼び出される関数です。なので、この中でrequire_onceしておけばよいのです。

当然、このオートロードの仕組みを利用するには、クラス名と、そのクラスの定義されているファイル名が一定の規則で結びつかないといけません。


そして次にデータベースの接続情報を設定しています。
ここではindex.phpに直書きしていますが、本来はiniファイルなどに書いて、それを読み込むような形にするほうがいいです。

あとはDispatcherを呼び出して、URLをもとにコントローラークラスへ処理を引き渡して終わりです。