1.4. MVC フレームワークの作成に取りかかる
フレームワークに何が必要かは十分に書いてきました。今こそ、私たちのフレームワークを実装する時です。まず、Web サーバーが必要です。Denwer を試すこともできますが、PHP を更新する必要があるかもしれません。
PHP 5.5.20 入りの Denwer は、このページからダウンロードできます:
https://drupalbook.org/ru/drupal/denwer-obnovlenie-php
または GitHub から
https://github.com/levmyshkin/denwer-php-5.5.20
私たちのフレームワークの動作は index.php ファイルから始まります。このファイルはレジストリからインスタンスを返し、必要なコントローラーを呼び出してレジストリの結果を渡します。コントローラーは今度は、必要なモデルを呼び出せます。

パターンの実装
私たちが議論したパターンを実装する方法はいくつかあります。私たちは可能な選択肢の 1 つを選びます。将来、いずれかのパターンの実装を変更することもできます。
始めましょう。前の記事の 1 つで、私たちのフレームワークの構造を分析したので、その構造に基づいてフォルダを作る必要があります。
では、ファイル Registry/registry.class.php を作成してください。このファイルに、私たちのレジストリのクラスを書きます。
<?php
/**
* レジストリオブジェクト
* レジストリパターンとシングルトンクラスを実装する
*
*/
class Registry {
/**
* 私たちのオブジェクトの配列
* @access private
*/
private static $objects = array();
/**
* 私たちの設定の配列
* @access private
*/
private static $settings = array();
/**
* 私たちのフレームワークの人間可読な名前
* @access private
*/
private static $frameworkName = 'Framework version 0.1';
/**
* 私たちのレジストリのインスタンス
* @access private
*/
private static $instance;
/**
* 私たちのレジストリのコンストラクタ
* @access private
*/
private function __construct()
{
}
/**
* オブジェクトにアクセスするためのシングルトンクラスのメソッド
* @access public
* @return
*/
public static function singleton()
{
if( !isset( self::$instance ) )
{
$obj = __CLASS__;
self::$instance = new $obj;
}
return self::$instance;
}
/**
* オブジェクトのコピーを防ぐ:起きた場合の E_USER_ERROR の問題
*/
public function __clone()
{
trigger_error( 'Cloning the registry is not permitted', E_USER_ERROR );
}
/**
* オブジェクトをレジストリに保存する
* @param String $object the name of the object
* @param String $key the key for the array
* @return void
*/
public function storeObject( $object, $key )
{
require_once('objects/' . $object . '.class.php');
self::$objects[ $key ] = new $object( self::$instance );
}
/**
* レジストリからオブジェクトを取得する
* @param String $key the array key
* @return object
*/
public function getObject( $key )
{
if( is_object ( self::$objects[ $key ] ) )
{
return self::$objects[ $key ];
}
}
/**
* 私たちのレジストリの設定を保存する
* @param String $data
* @param String $key the key for the array
* @return void
*/
public function storeSetting( $data, $key )
{
self::$settings[ $key ] = $data;
}
/**
* 私たちのレジストリの設定を取得する
* @param String $key the key in the array
* @return void
*/
public function getSetting( $key )
{
return self::$settings[ $key ];
}
/**
* フレームワーク名を取得する
* @return String
*/
public function getFrameworkName()
{
return self::$frameworkName;
}
}
?>
では、私たちのレジストリはどう動作し、どうオブジェクトを保存するのでしょうか?
- オブジェクトは配列の形で保存される
- 新しいオブジェクトがレジストリに追加されると、クラスファイルも追加され、オブジェクトのインスタンスが作られて配列に追加される
- オブジェクトは、そのキーを getObject メソッドに渡すことで返される
レジストリオブジェクトの別のコピーが作られるのは、どう防がれるのでしょうか?
- コンストラクタは private で、これによりオブジェクトを直接作るのを防げる
- オブジェクトのクローンはエラーを引き起こす
- 私たちのフレームワークからレジストリオブジェクトにアクセスしたいが、今実行中のファイルからはそれができない場合、静的メソッド singleton(Registry::singleton())を使ってレジストリのインスタンスを取得できる。
レジストリができたので、フレームワークの動作を呼び出しレジストリにアクセスするために、index.php を書きましょう。
Index.php
Index.php — これは私たちのフレームワークの動作の出発点です。
この後、.htaccess ファイルを使って人間可読 URL を作る機能も追加します。ひとまず、index.php のコードを見てみましょう:
<?php
/**
* Framework
* Framework loader - acts as a single point of access to the Framework
*
*/
// セッションを開始する
session_start();
// いくつかの定数を設定する
// どのスクリプトからでも簡単に取得できるよう、フレームワークのルートを設定する
define( "APP_PATH", dirname( __FILE__ ) ."/" );
// 私たちのフレームワーク以外からのスクリプト呼び出しを避けるためにこれを使う
define( "FW", true );
/**
* オートロードのマジック関数
* 必要なときに必要な -controller- を呼び出せるようにする
* @param String the name of the class
*/
function __autoload( $class_name )
{
require_once('Controllers/' . $class_name . '/' . $class_name . '.php' );
}
// 私たちのレジストリを接続する
require_once('Registry/registry.class.php');
$registry = Registry::singleton();
// すべて動作していることを確認するためにフレームワーク名を出力する
print $registry->getFrameworkName();
exit();
?>
すべて正しければ、私たちのフレームワーク名のメッセージが出力されるはずです:
Framework version 0.1
現時点で私たちの index.php がどう動作するか見てみましょう:
- フレームワークのどこでもデータを記録し取得できるよう、セッションを呼び出す。
- 私たちのフレームワークのルートフォルダを定義する。これにより、サイトのルートからではなくフォルダから正常に動作できる。
- オートロードでコントローラーを読み込む
- レジストリクラスを接続する
- そして、私たちのフレームワーク名を出力する。