第7章 MVCモデルのフレームワーク

7.2 MVCモデルのフレームワークでの組み立て方

 本節ではMVCモデルのフレームワークの組み立て方について説明します。
 前節で触れたとおり、PHPのMVCモデルでは、Modelを担当するインクルードファイル(.incファイル)、Viewを担当する.phtmlファイル、Controllerを担当する.phpファイルが必要になります。
 今回はサンプルコードとして、数字当てゲーム(MVC版)を使用します。以下URLからサンプルコードをダウンロードしてmyproj_framework_basicプロジェクトにコピーしてください。(ファイル構成は次ページを参照)

https://kanda-it-school-square.com/?wpdmdl=4292

7.2.1 数字当てゲームMVC版の概要

 このプログラムは、入力フォームから0から9までの予想数字を入力し、ランダムで設定された正解数字の判定を行います。予想数字と正解数字が同じ場合は「!!大正解!!」というメッセージを出力し、異なる時はヒントのメッセージを出力します。また、0から9以外の数字が入力された場合はエラーメッセージを出力します。

実行結果

ファイル構成

 それぞれのファイルの記述内容と処理の流れについて、解説していきます。

7.2.2 incファイル

 まず、Modelとして用意されたincファイルについて解説します。

ソースコード

ソース・フォルダー  :myproj_framework_basic/ch07
ファイル名      :number_hit2_mvc_model.inc
アクセスURL    :number_hit2_mvc.phpから呼び出される

➢ number_hit2_mvc_model.inc

    <?php
    //=====================================================================================
    // プログラム名  :数字当てゲーム(Ver2)MVCモデル
    // プログラム説明:画面項目クラス
    // 作成者        :神田ITスクール
    // 作成日        :2020/9/1
    //=====================================================================================
    class number_hit2_mvc_model{

    	//--------------------------------------
    	//各フィールド変数宣言
    	//--------------------------------------
    	private $userNum;						//ユーザー入力数字
    	private $ansNum;						//正解数字
    	private $counter;						//処理回数
    	private $execute;						//処理種別
    	private $msg;							//メッセージ
    	private $btnName;						//ボタン名

    	/**
    	 *   概要:__construct
    	 *   機能説明:コンストラクタ
    	 */
    	public function __construct(){
    		$this->init();
    	}

    	/**
    	 *   概要:init
    	 *   機能説明:フィールド変数初期化
    	 */
    	public function init() {
    		$this->userNum	 = 0 ;				//ユーザー入力数字
    		$this->ansNum	 = 0 ;				//正解数字
    		$this->counter	 = 0 ;				//挑戦回数
    		$this->execute	 = '';					//処理種別
    		$this->msg		 = '';					//メッセージ
    		$this->btnName	 = '';					//ボタン名
    	}

    	//--------------------------------------
    	//各setterメソッドを宣言
    	//--------------------------------------
    	//ユーザー入力数字
    	public function setUserNum($param){
    		$this->userNum = $param;
    	}
    	//正解数字
    	public function setAnsNum($param){
    		$this->ansNum = $param;
    	}
    	//挑戦回数
    	public function setCounter($param){
    		$this->counter = $param;
    	}
    	//処理種別
    	public function setExecute($param){
    		$this->execute = $param;
    	}
    	//エラーメッセージ
    	public function setMsg($param){
    		$this->msg = $param;
    	}
    	//ボタン名
    	public function setBtnName($param){
    		$this->btnName = $param;
    	}

    	//--------------------------------------
    	//各getterメソッドを宣言
    	//--------------------------------------
    	//ユーザー入力数字
    	public function getUserNum(){
    		return $this->userNum;
    	}
    	//正解数字
    	public function getAnsNum(){
    		return $this->ansNum;
    	}
    	//挑戦回数
    	public function getCounter(){
    		return $this->counter;
    	}
    	//処理種別
    	public function getExecute(){
    		return $this->execute;
    	}
    	//メッセージ
    	public function getMsg(){
    		return $this->msg;
    	}
    	//ボタン名
    	public function getBtnName(){
    		return $this->btnName;
    	}

    	/**
    	 *   概要:getForm
    	 *   機能説明:画面遷移時にフォームに入力されたデータを受け取り、フィールド変数に代入
    	 */
    	public function getForm() {
    	    //ユーザー入力数字
    		if (isset($_POST['userNum'])){
    			$this->setUserNum($_POST['userNum']);
    		}
    		//正解数字
    		if (isset($_POST['ansNum'])){
    			$this->setAnsNum($_POST['ansNum']);
    		}
    		//挑戦回数
    		if (isset($_POST['counter'])){
    			$this->setCounter($_POST['counter']);
    		}
    		//処理種別
    		if (isset($_POST['execute'])){
    			$this->setExecute($_POST['execute']);
    		}
    	}

    	/**
    	 *  概要:processing
    	 *  機能説明:処理種別にあった処理を行い、各種判定を行う
    	 */
    	public function processing(){
    		//画面表示用のボタン名を設定
    		$this->setBtnName("結果表示");

    		/* 処理種別に応じて処理を分岐 */
    		if($this->getExecute() == "" || $this->getExecute() == "retry"){
    		    /* 処理種別が初期起動or再挑戦の場合 */
    			//正解数字をランダムで発生させる
    			$this->setAnsNum(mt_rand(0, 9));

    			//挑戦回数を0に設定する
    			$this->setCounter(0);

    			//処理種別をplaying(ゲーム中)に変更
    			$this->setExecute("playing");

    		}else{
    			/* 結果表示ボタン押下から遷移した場合 */

    			//挑戦回数を1増やす
    			$this->setCounter($this->getCounter() + 1);

    			//入力数字を判定
    			if($this->getUserNum() < 0 || $this->getUserNum() > 9 ){
    				//数字が範囲外の場合
    				$this->setMsg("エラー!!0~9の数字を入力して下さい。");

    			}else if($this->getUserNum() == $this->getAnsNum()){
    				//正解の場合
    			    $this->setMsg("!!大正解!!");

    				//画面表示用のボタン名を設定
    				$this->setBtnName("もう一度挑戦");

    				//処理種別をretry(もう一度挑戦)に変更
    				$this->setExecute("retry");

    			}else if($this->userNum > $this->ansNum){
    				//正解より大きい場合
    			    $this->setMsg($this->getUserNum() . "より小さいです。");

    			}else if($this->userNum < $this->ansNum){
    				//正解より小さい場合
    			    $this->setMsg($this->getUserNum() . "より大きいです。");

    			}
    		}
    	}
    }
    ?>
	

解説   
 かなり長いソースコードですが、役割として処理をまとめると、以下のような構成になっています。これらはMVCモデルのフレームワークで扱うクラスの必要最低限の構成要素となります。   
 ①フィールド変数の宣言(13~18行目)   
 ②コンストラクタの定義(20~26行目)   
 ③フィールド変数の初期化(32~39行目)   
 ④setterメソッドの定義(45~67行目)   
 ⑤getterメソッドの定義(73~95行目)   
 ⑥getForm()メソッドの定義(101~118行目)   
 ⑦processing()メソッドの定義(124~171行目)   
 それぞれの処理内容について、解説していきます。
 まず「①フィールド変数の宣言」では、このプログラムを表示する際に使用するフィールド変数を宣言しています。今回のプログラムで扱うフィールド変数は、いずれもインスタンスメンバなので、staticは付けません。   

 次に「②コンストラクタの定義」では、オブジェクト生成時に自動で呼び出されるコンストラクタを定義しています。今回のプログラムでは、フィールド変数の初期化を行うini()メソッドを呼び出し、オブジェクト生成時に初期値が設定されるようにしています。

 ここで呼び出された「③フィールド変数の初期化」では、各フィールド変数の初期値を設定しています。数字を扱うものは0、それ以外は空文字で初期化しています。

 次の「④setterメソッドの定義」と「⑤getterメソッドの定義」については、アクセサメソッドの定義部分となります。すべてのフィールド変数についてのsetetr/geterを用意します。

 今度の「⑥getForm()メソッドの定義」では、遷移元のフォームから送信されたデータを、対応するフィールド変数に格納しています。初回の画面遷移の時は遷移元のデータがないこともあるので、if文を使って、フォームから送られたデータがある時だけsetterメソッドを呼び出してフィールドを上書きしています。また、今回はPOST送信のデータだけなので、$_POSTのパラメータのみ代入していますが、GET送信でも来るかもしれない画面の場合は、両方の送信方法でも値を設定できるようにif-else文を使います。

 最後に「⑦processing()メソッドの定義」では、各フィールド変数の値を元に、画面表示を行うための処理を行います。今回の数字当てプログラムでは、処理種別を扱うフィールド変数$executeの値に応じて初回遷移時か、結果表示ボタン押下時かを判断してそれぞれの画面表示に向けた処理を行っています。130~138行目が初回遷移時、141~170行目が結果表示ボタン押下時の処理になっています。

 今回はprocessing()メソッド内で画面遷移に関わる全ての処理を行なっていますが、必要に応じて別のメソッドに機能をまとめて、それをprocessing()メソッドから呼び出すこともあります。プログラムの仕様に合わせて臨機応変に組み立てられるようにしましょう。
 number_hit2_mvc_model.incの解説は以上となります。

7.2.3 phpファイル

 Controllerとして用意されたphpファイルについて解説します。MVCモデルのフレームワークを動かす際は、このphpファイルを実行することで動かします。

ソースコード

ソース・フォルダー  :myproj_framework_basic/ch07
ファイル名      :number_hit2_mvc.php
アクセスURL    :http://localhost/myproj_framework_basic/ch07/number_hit2_mvc.php

➢ number_hit2_mvc.php

    <?php
    //=====================================================================================
    // プログラム名  :数字当てゲーム(Ver2)MVCモデル
    // プログラム説明:キーボードから2桁数字を入力してもらい正解数字を当てるプログラム
    // 作成者        :神田ITスクール
    // 作成日        :2020/9/1
    //=====================================================================================
        //関連ファイルの読み込み
        require_once("number_hit2_mvc_model.inc");
        
        //クラスをインスタンス化
        $model = new number_hit2_mvc_model();
        
        //画面項目取得(form値&hidden値等)
        $model->getForm();
        
        //処理(処理種別等で処理する内容を判定)
        $model->processing();
        
        //画面呼出し(処理結果に応じた値をクラスから受け取り画面に表示する)
        require_once("number_hit2_mvc.phtml");
    ?>
	

解説

 このファイルで行っている処理は、以下の5つです。これらは、MVCモデルのフレームワークでのphpファイルの基本の処理の流れとなっています。
 ①関連ファイルの読み込み
 ②クラスのオブジェクト生成
 ③フォームデータの取得
 ④画面表示に向けての処理
 ⑤画面表示するphtmlファイルの読み込み
 それぞれの処理内容について、解説していきます。
 まず9行目で「①関連ファイルの読み込み」を行っています。これによって、別のファイルに定義されているクラスを使ってのオブジェクト生成やメソッドの呼び出しができるようにしています。また、ファイル読み込みの際は、安全性の高いrequire_once()関数を使っています。今回は1つのインクルードファイルだけを読み込んでいますが、必要に応じて複数のインクルードファイルを読み込むこともあるので、重複して読み込まれることがないようにしています。

 次に12行目では「②クラスのオブジェクト生成」を行っています。先程読み込んだファイルの中に定義されいてるクラスのオブジェクトを生成することで、フィールド変数やメソッドを使う準備をしています。

「③フォームデータの取得」では、②で作成したオブジェクトのgetForm()メソッドを呼び出すことで、遷移元の画面から送信されたフォームデータをオブジェクト内のフィールド変数に格納しています。これによって、遷移元の画面からのデータの受け渡しができるようにしています。

 続いて「④画面表示に向けての処理」では、オブジェクト内のprocessing()メソッドを呼び出して、受け取ったフォームデータ等を元に次の画面に表示する内容を設定してもらいます。

 最後に「⑤画面表示するphtmlファイルの読み込み」として、number_hit2_mvc.phtmlファイルの読み込みをrequire_once()関数で行なっています。これによって、pthmlファイルに記述されている画面表示内容がブラウザ上に出力されます。この時、phpファイルの続きの処理としてphtmlファイルの処理が行われるので、④までの処理を終えた状態のオブジェクト変数$modelがそのままnumber_hit2_mvc.phtmlでも使えるようになります。

 number_hit2_mvc.phpファイルの処理の流れは以上となります。

7.2.4 phtmlファイル

 最後にnumber_hit2_mvc.phtmlファイルの処理の流れについて、解説します。

ソースコード

ソース・フォルダー  :myproj_framework_basic/ch07
ファイル名      :number_hit2_mvc.phtml
アクセスURL    :number_hit2_mvc.phpから呼び出される

➢ number_hit2_mvc.phtml

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
        <head>
            <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
            <title>数字当てゲーム(Ver2)MVC版</title>
        </head>
        <body>
    		<h2><b>■数字当てゲームMVC版(0~9の数字を入力して下さい)■</b></h2>
    		<form action="./number_hit2_mvc.php" method = "POST">
     			0~9までの数字を入力して下さい:<input type="text" name="userNum"   size="4"  value="<?php echo $model->getUserNum()?>" />
     			<input type="submit" name="ボタン" value="&nbsp;<?php echo $model->getBtnName()?>&nbsp;" /><br/><br/>
     			<!-- textボックスとは別に数字当てゲームに必要な値を各hiddenに設定 -->
     			<!-- ①処理種別、②挑戦回数、③初期動作時に設定正解数値 -->
      			<input type="hidden"  name="execute" value="<?php echo $model->getExecute()?>" />
      			<input type="hidden"  name="counter"  value="<?php echo $model->getCounter()?>" />
      			<input type="hidden"  name="ansNum"  value="<?php echo $model->getAnsNum()?>" />
      		</form>
      		<?php 		//処理回数が1回以上の場合結果を表示する
      			if($model->getCounter() > 0){
      				//挑戦回数が1回以上の場合結果を表示する
            ?>		予想数字:<?php echo $model->getUserNum()?><br/>
              		正解数字:<?php echo $model->getAnsNum()?><br/>
              		処理回数:<?php echo $model->getCounter()?><br/>
               		<hr />
            <?php 	//メッセージを表示する
              		echo $model->getMsg();
              	}
            ?>
      	</body>
    </html>
	

解説
 このphtmlファイルをEclipseで開くと、オブジェクト変数$modelはプログラム内で未定義だという警告文(Variable ‘$model’ is undefined)が表示されますが、このphtmlファイルはnumber_hit2_mvc.phpの続きとして出力されるので、number_hit2_mvc.phpから呼び出された時は、phpファイル内で宣言されたオブジェクト変数$modelをそのまま使うことができます。

 今回はフィールド変数のアクセス修飾子はprivateなので、フィールド変数の値を画面表示する際は、getterメソッドを呼び出す必要があります。
 以上が、MVCモデルのフレームワークで1つの画面が表示されるまでの流れとなります。


NEXT>> 7.3 本章のまとめ