昨日はひどいMVCになってしまいましたので、もう少しマシになるように書いていきます。
ここにある特集サイト
(ショッピングカート作成)が解り易かったのでここを参考に自分なりによりシンプルになるようにしてみます。
まず「Model」部分は値を保持する必要性があるのでクラス化します。
「View」に関してはとりあえずクラス化せずに外部ファイル分けにとどめて処理は前回同様、テンプレートエンジンは使わないでいきたいと思います。
直接呼ばれることになる「Controller」も同様にクラス化しなくてもいけそうです。
そして、多人数で一つのシステムを開発する場合を考えてこれらはそれぞれ最低でも3つのファイルに独立させておくこととします。
ということで、「Model」にはビジネスロジックとなる作成サイトに則したデータの読み書き処理いわゆるCRUD(Create,Read,Update,Delete)を関数分けして、「View」の処理コードはほぼ固定のままでViewから読み込むテンプレート類をデザイナーが独立して作成できる形にして、「Controller」にはswitch文で処理分けしてModelに書いた関数でデータ操作していく形でいけそうな気がします。
[テンプレート規則]
デザインがされていてコンテンツのない抜け殻のHTML
%TITLE%, %BODY%のように置き換え部分を「%」で囲ったキーワードという形式にします。
■init.tpl
<body>
<h3>%TITLE%</h3>
<form action="%ACTION%" method="post">
<input type="hidden" name="act" value="%MOVE%">
<input type="text" name="t1">%t1%<br>
<input type="submit" value="送信">
</form>
</body>
■end.tpl
<body>
<h3>%TITLE%</h3>
<form action="%ACTION%" method="post">
<input type="text" name="t1">%t1%<br>
<input type="submit" value="送信">
</form>
</body>
テンプレートはデザインもなにもない適当なものです。
今回は表示ができてるかどうかを見るだけにとどめておくということで
■inc_model.php
<?php
class model
{
// データ保持用
var $val= array();
// コンストラクタ
function model()
{
// このクラス内で起きたエラーメッセージをセット
$this->val['errmsg']= '';
}
// ビジネスロジックのCRUD群(ファイルやDBなどデータ操作)
function create($id)
{
// create処理
return "createが成功したかどうかの真偽値";
}
function read($id)
{
// read処理
return "読み出しデータ値";
}
function update($id, $data)
{
// update処理
return "updateが成功したかどうかの真偽値";
}
function delete($id)
{
// delete処理
return "deleteが成功したかどうかの真偽値";
}
}
?>
■inc_view.php
<?php
function view($obj)
{
$tpl= empty($obj->val['errmsg']) ? $obj->val['template'] : $obj->val['errtpl'];
$html= file_get_contents($tpl);
echo preg_replace('/%(\w+)%/e', 'isset($obj->val["$1"]) ? $obj->val["$1"] : ""', $html);
exit;
}
?>
■mvc.php(最初に直接呼ばれるControllerに当たるファイル)
<?php
error_reporting(E_ALL);
ini_set("display_errors", 1);
// 外部ファイルのModelとViewを呼び出し
include("./inc_model.php");
include("./inc_view.php");
// Controller内関数
function reqdata($key)
{
return isset($_REQUEST[$key]) ? $_REQUEST[$key] : '';
}
// データ保持用のModelクラスをインスタンス化してテンプレートおよび置換データをセット
$obj= new model;
$obj->val['errtpl']= 'error.tpl';
$obj->val['ACTION']= $_SERVER['SCRIPT_NAME'];
$act= reqdata('act');
switch ($act){
case "act1": $tpl= "init.tpl";
$obj->val['TITLE']= "ACT1画面";
$obj->val['MOVE']= "act2";
$obj->val['t1']= htmlspecialchars(reqdata('t1'));
break;
case "act2": $tpl= "end.tpl";
$obj->val['TITLE']= "最終画面";
$obj->val['t1']= htmlspecialchars(reqdata('t1'));
break;
default: $tpl= 'init.tpl';
$obj->val['TITLE']= "初期画面";
$obj->val['MOVE']= "act1";
}
$obj->val['template']= $tpl;
// 保持されたデータをViewに渡して表示させる
view($obj);
?>
ここではModelの関数を適当に書いてみたので使ってないですが、冗長になるデータの読み書き処理がModelにまとまることでController側では制御がその分スッキリして見通しがよくなるのでswitch文でまとめやすい感じがします。
どの画面でどのテンプレートを使ってるかとか、act値で次にどの画面に遷移させているかとかが見やすいですね。
次回は実際に実践的なものを作ってみたいと思います。