ビュー

ビューの役割

MVCのVにあたるビューです。

ビューは最終的なHTML出力を担当します。
コントローラーがモデルクラスを利用して処理結果を受け取り、
その処理結果を今度はビュークラスに渡して、ビュークラスがそれをもとにHTML生成・出力を行う。
という感じです。

デザインとロジックの分離

PHPの特徴として、HTML埋め込み型の言語である事が挙げられます。
HTMLの中に直接、phpタグで囲んでPHPのソースコードを書くわけです。

これってお手軽な反面、ちょっと複雑なシステムになってくるとHTMLとPHPのソースコードが複雑に絡み合って大変な事になります。ちょっとデザインを変えたいとなっても、PHPのソースコードを直接さわることになり、下手をすればPHPの挙動にも影響を与えるなんてことになりかねません。

そこで最近はデザインとロジックの分離という考え方が一般的になってきています。
PHPのソースコード中にHTMLは書かない、HTMLファイル中にPHPのソースコードは書かない、というものです。
ファイルレベルで完全に分離するのです。


どうやってそれを実現するかですが、「テンプレートエンジン」と呼ばれるものを利用します。
HTMLファイルの代わりに、動的に変化して欲しい部分だけを変数化した「テンプレート」を作成し、PHPで取得したデータをテンプレートに割り当てるという感じです。

そしてその結果として完成したHTMLを出力します。

Smarty

最も有名で、ほぼ標準と呼べるテンプレートエンジンが「Smarty」と呼ばれるものです。
Smartyに関しては解説しているサイトが山ほどあるので、詳細についてはそちらを見てみてください。

Smartyのテンプレートの例を紹介します。

bbs.tpl
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>掲示板</title>
</head>
<body>

<form method="post" action="">
  <input type="text" name="name" /><br />
  <input type="text" name="title" /><br />
  <textarea name="message"></textarea><br />
  <input type="hidden" name="parent_no" value="{$parentNo}" />
  <input type="submit" name="write" value="書き込む" />
  <span class="message">{$message}</span>
</form>

{foreach from=$parents item=parent}
<div class="parent">
  <div class="header">
    No.{$parent.No} {$parent.Title} 投稿者:{$parent.Name}
    <form method="post" action="">
      <input type="submit" name="res" value="返信" />
      <input type="hidden" name="parent_no" value="{$parent.No}" />     
    </form>
    <form method="post" action="">
      <input type="submit" name="del" value="削除" />
      <input type="hidden" name="no" value="{$parent.No}" />
    </form>
  </div>
  <div class="message">{$parent.Message}</div>
 

パッと見、普通のHTMLファイルっぽく見えます。
しかし、ところどころ、{$~}みたいな形式の部分があります。これはsmartyタグと呼ばれているもので、これが変数となります。PHPから、この変数部分に値を割り当てるのです。

もっと、ごく単純な例で見てみましょう。

sample.tpl
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Smartyサンプル</title>
</head>
<body>

<p>Hello! {$abc}</p>

</body>
</html>

{$abc}の部分以外は普通のHTMLです。
この{$abc}の部分にPHPから変数を割り当てます。

PHPのソースコードを見てみましょう。

sample.php
<?php

$smarty = new Smarty();
// テンプレート格納ディレクトリを指定
$smarty->template_dir = '/aaa/bbb/Smarty/templates/';
// テンプレートの{$abc}に「World」という文字列を割り当てる
$smarty->assign('abc', 'World');
// 結果出力
$smarty->display('sample.tpl');

?>
Hello! World

Smartyはクラスです。
見たとおり、テンプレートへの変数の割り当てはとても単純に行えます。

Smartyタグには配列を処理する機能もあります。

names.tpl
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Smartyサンプル</title>
</head>
<body>

<ul>
  {foreach from=$names item=name}
  <li>{$name}</li>
  {/foreach}
</ul>

</body>
</html>
names.php
<?php

$smarty = new Smarty();
$smarty->template_dir = '・・・';

$ar = array('一郎', '二郎', '三郎');
$smarty->assign('names', $ar);
$smarty->display('names.tpl');

?>
・一郎
・二郎
・三郎

こんな感じです。
PHPで取得した配列データをそのまま割り当ててforeachでテーブルタグを組み立てるっていうような使い方をしたりします。

if文なんかも書けるんですが、
あんまり複雑にやりすぎると、結局ロジックみたくなってしまって元も子もないってことになってしまうので、
あくまでロジックはPHP側でやって、結果の変数を割り当てるという考え方を基本にすべきです。


Smartyは高機能で、本当にいろいろ便利なことが出来るのですが、
ここではSmartyの詳細については触れないので、
専門のサイトなどを見てみてください。

MVCにおけるビュークラス

で、ビュークラスについてですが、
これはそのまんまSmartyをビュークラスとして使うのが一つの方法です。

もしくはSmartyを拡張、または内包した新しいクラスをビュークラスとするのもありです。

Smartyなんか関係なく自作するってんならそれもありです。
何にしても、基本的にはテンプレート方式にしてロジックとデザインは完全分離するのを基本とすべきです。

仮にSmartyをビュークラスとして使用する場合のコントローラークラスの実装例を見てみましょう。

<?php

class CartController
{
    private $view;

    public function __construct()
    {
        // ビュー
        $this->view = new Smarty();
        $this->view->template_dir = '../view/templates';
    }

    public function displayAction()
    { 
        // リクエスト情報取得
        $req= new Request();
        $params = $req->getParam();
        $userId = $params['user_id'];

        // モデルインスタンス生成
        $cart = new Cart();
        $cartProduct = new CartProduct();

        // データ取得
        $cartInfo = $cart->getUserCart($userId);
        $products = $cartProduct->getProductList($cartInfo['cart_id']);

        // テンプレートへ変数割り当て
        $this->view->assign('cart_info', $cartInfo);
        $this->view->assign('prouducts', $products);

        // テンプレート表示
        $this->view->display('cart/display.tpl');
    }

}

?>

もっと作り込むべき部分は多々ありますが、
基本的にはコントローラー内でのビューの利用はこんな感じになります。