Viewクラスで画面生成する

MVCフレームワーク

Viewクラスというのは、簡単に言えばタイトルの通りHTMLを読み込んで呼び出し元に返す処理を行い、表示する画面を生成します。それっぽく言えばViewクラスをレンダリングするのがViewクラスです。
このページではこの画面を出力するためのViewクラスについて学んでいきます。

HTMLをレンダリングする

MVCのVに当たるViewクラスの作成を行います。HTMLを直接置くようなことはせずアプリケーション側で用意することにします。フレームワークのViewにはHTMLを読み込んで呼び出し元に返す処理を定義します。アプリケーション側で用意するHTMLは、それ専用のフォルダを用意してそこに配置します。また、そのフォルダはコントローラーごとに作成し、その中に格納します。そのため、ファイルを読み込む時はその格納したファイルのパスが必要になります。

Viewクラスの作成

早速ですがViewクラスを作成していきましょう。

プロパティを用意する

まずプロパティを用意します。

Class View {
    protected $_pageTitle = array();//ページタイトル
    protected $_viewData ;//ビューファイルへ渡すデータ
    protected $_viewPath;//ビューファイルを格納しているディレクトリのパス
}

コンストラクターを定義しプロパティにデータをセットする

Controllerクラスのrender()メソッドがVIewクラスのインスタンス化を行うときに呼ばれるコンストラクターを用意します。このコンストラクターで、渡された引数をプロパティに代入します。

public function __construct($viewPath, $viewData = array()) {
    $this->_viewPath = $viewPath(); //渡されたビューディレクトリのパスを格納
    $this->_viewData = $viewData;//渡されたビューファイルのパス、Request・Sessionオブジェクト情報を配列で格納
}

レイアウトファイルに渡すデータを設定する

ビューファイル側で渡すデータを設定するためのメソッドを定義します。プロパティに代入するだけです。

public function setPageTitle($name, $value) {
    $this->_pageTitle[$name] = $value;
}

ビューファイルを読み込むrender()メソッド

ここでControllerクラスのrender()メソッドに呼び出されるViewクラスのrender()メソッドを作成します。ビューファイルからコンテンツを読み込んで処理を行います。

呼び出し側から渡される引数を用意する

このrender()メソッドに渡される引数はビューファイルのパスの基になる情報、配列データ、レイアウトファイルの指定があればファイル名です。

/**
* 
* @param $filepath    「コントローラー名/アクション名」といったビューファイルのパス情報
* @param $params     アクションメソッドから渡される配列
* @param $template     レイアウトファイル名
*/

public function render($filepath,  $params = array(), $template = false){


}

ビューファイルへのパスを生成


まず_viewPathプロパティの値と$filepathパラメーターの値を「/」を間にして連結し、ビューファイルへのパスを生成します。ビューファイルの名前は「アクション名.php」という風な名前を付ける決まりとしておきます。
これによって「~/view/コントローラー/アクション.php」というようにパス情報が完成します。

/**
* @var _viewPath ビューファイルまでのパス情報
* @var $filepath コントローラー名/アクション名といったパス情報
*/

$view = $this->_viewPath. '/'. $filepath. '.php';

_viewDataプロパティに$paramsをマージして変数展開

_viewDataプロパティはビューファイルへ渡すビューファイルのパス、Request・Sessionオブジェクト情報の配列でしたね。
そして$paramsはアクションメソッドから渡されるデータです。
これらをextract()関数で配列のキーごとに変数とその変数に入る値を作成します。登録するのは、array_merge()関数でマージした_viewDataとアクションメソッドから渡されてきた$paramsに格納されている配列データです。これをしておくと、配列のキー名を変数として指定して、値を出し入れできます。

extract(array_merge($this->_viewData, $params));

array_merge()とextract()について簡単に説明しときます。
array_merge()とは複数の配列を結合させて一つの配列にまとめることができます。

$array1 = [a,b,c];
$array2 = [1, 2, 3];

 
//配列を結合する
$array = array_merge($array1, $array2);
 
print_r($array);

//結果
Array
(
    [0] => a
    [1] => b
    [2] => c
    [3] => 1
    [4] => 2
    [5] => 3
)

extract()は連想配列のキーを変数にして値をその変数に格納することができます。ここでは簡単な使い方についてしか説明しないので、詳細は公式ドキュメントを見たり検索してみてください。

$array1 = ['ary1'=>'a', 'ary2'=>'b', 'ary3'=>'c'];

extract($array1);

print $ary1; //a
print $ary2 //b
print $ary3; //c

次に、バッファリングを用いてビューファイルに格納されているコンテンツを読み込みます。バッファリングする方法は以下のとおりです。

    ob_start();//出力バッファをONに
    ob_implicit_flush(0);//自動フラッシュを無効に
    require $view;//ビューファイルを読み込んで出力バッファに内容が格納される
    $content = ob_get_clean();//出力バッファの内容を変数に格納してバッファリングを終了

最後にレイアウトファイルを読み込んでHTMLドキュメントを生成します。読み込んだ内容を返しますが、各ビューファイルはドキュメントの本体部分だけでヘッダーなど他の情報はありません。基本構造部分は別に、レイアウトファイルで定義しておいてこの中に本体部分を読み込んで1つのドキュメントにします。そのために、再度render()メソッドを呼び出します。
$templateパラメーターにレイアウトファイル名が格納されていれば読み込みを行います。
ビューファイルのコンテンツを連想配列としてマージし、メソッドの$parametersパラメーターに渡します。最初にメソッドが呼ばれたときと同じデータにコンテンツを加えたデータを渡すということです。

if($template) {
    $content = $this->render($template, array_merge($this->_pageTitle, array('_content' => $content)));
}



そしてレイアウトファイルの決まりとして、HTMLドキュメントの中でprint $_contentで埋め込むようにします。

<html>
.........

<body>
    <div id="main">
        <?= $_content;?>
    </div>
</body>
</html>

VIEWクラスのまとめ(コード)

小分けにして説明してきましたが、まとめると以下のようにコードを記述します。

<?php

class View{
    protected $_pageTitle = array();//ページタイトル
    protected $_viewData ;//ビューファイルへ渡すデータ
    protected $_viewPath;//ビューファイルを格納しているディレクトリのパス


    public function render($filepath, $aprameters = array(), $template = false) {
    $view = $this->_viewPath . '/' . $filepath . '.php';
    extract(array_merge($this->_viewData, $parameters));

    ob_start();//出力バッファをONに
    ob_implicit_flush(0);//自動フラッシュを無効に
    require $view;//ビューファイルを読み込んで出力バッファに内容が格納される
    $content = ob_get_clean();//出力バッファの内容を変数に格納してバッファリングを終了

        if($template) {
            $content = $this->render($template, array_merge($this->_pageTitle, array('_content' => $content)));
        }
        return $content;
    }

    public function es($string){
        return htmlspecialchars($string, ENT_QUOTES, 'UTF-8');
    }
}
?>

コメント

タイトルとURLをコピーしました