ゼロから始めるPHP講座Vol.42 MVCモデル①~MVCモデルとは?

ゼロから始めるPHP講座Vol.42 MVCモデル①~MVCモデルとは?
目次
  1. ゼロから始めるPHP講座 MVCモデル①~MVCモデルとは?
  2. MVCモデルとは

ゼロから始めるPHP講座 MVCモデル①~MVCモデルとは?

MVCモデルとは

ソフトウェアの設計モデルの1つです。 処理の中核を担う「Model」、表示・出力を司る「View」、入力を受け取りその内容に応じてViewとModelを制御する「Controller」の組み合わせでシステムを実装します。

php-mvc1-639

文章だけだと理解が難しいと思いますので、まずはMVCモデルに沿って実装をしてみましょう。

前回の「ユーザー定義関数②」で作成した商品の一覧を表示するページ(func_sample.php)を、以下のように4つのファイルへ分割してください。controller.phpのみ、追加コードがあります。 ファイル名: const.php, model.php, view.php, controller.php

<?php

define('TAX', 1.05);  // 消費税

define('DB_HOST',   'localhost'); // データベースのホスト名又はIPアドレス
define('DB_USER',   'username');  // MySQLのユーザ名
define('DB_PASSWD', 'passwd');    // MySQLのパスワード
define('DB_NAME',   'dbname');    // データベース名

define('HTML_CHARACTER_SET', 'UTF-8');  // HTML文字エンコーディング
define('DB_CHARACTER_SET',   'UTF8');   // DB文字エンコーディング
<?php

/**
* 税込み価格へ変換する(端数は切り上げ)
* @param str  $price 税抜き価格
* @return str 税込み価格
*/
function price_before_tax($price) {
    return ceil($price * TAX);
}

/**
* 商品の値段を税込みに変換する(配列)
* @param array  $assoc_array 税抜き商品一覧配列データ
* @return array 税込み商品一覧配列データ
*/
function price_before_tax_assoc_array($assoc_array) {

    foreach ($assoc_array as $key => $value) {
        // 税込み価格へ変換(端数は切り上げ)
        $assoc_array[$key]['price'] = price_before_tax($assoc_array[$key]['price']);
    }

    return $assoc_array;

}

/**
* 特殊文字をHTMLエンティティに変換する
* @param str  $str 変換前文字
* @return str 変換後文字
*/
function entity_str($str) {
    return htmlspecialchars($str, ENT_QUOTES, HTML_CHARACTER_SET);
}

/**
* 特殊文字をHTMLエンティティに変換する(2次元配列の値)
* @param array  $assoc_array 変換前配列
* @return array 変換後配列
*/
function entity_assoc_array($assoc_array) {

    foreach ($assoc_array as $key => $value) {

        foreach ($value as $keys => $values) {
            // 特殊文字をHTMLエンティティに変換
            $assoc_array[$key][$keys] = entity_str($values);
        }

    }

    return $assoc_array;

}

/**
* DBハンドルを取得
* @return obj $link DBハンドル
*/
function get_db_connect() {

    // コネクション取得
    if (!$link = mysqli_connect(DB_HOST, DB_USER, DB_PASSWD, DB_NAME)) {
        die('error: ' . mysqli_connect_error());
    }

    // 文字コードセット
    mysqli_set_charset($link, DB_CHARACTER_SET);

    return $link;
}

/**
* DBとのコネクション切断
* @param obj $link DBハンドル
*/
function close_db_connect($link) {
    // 接続を閉じる
    mysqli_close($link);
}

/**
* クエリを実行しその結果を配列で取得する
*
* @param obj  $link DBハンドル
* @param str  $sql SQL文
* @return array 結果配列データ
*/
function get_as_array($link, $sql) {

    // 返却用配列
    $data = array();

    // クエリを実行する
    if ($result = mysqli_query($link, $sql)) {

        if (mysqli_num_rows($result) > 0) {

            // 1件ずつ取り出す
            while ($row = mysqli_fetch_assoc($result)) {
                $data[] = $row;
            }

        }

        // 結果セットを開放
        mysqli_free_result($result);

    }

    return $data;

}

/**
* 商品の一覧を取得する
*
* @param obj $link DBハンドル
* @return array 商品一覧配列データ
*/
function get_goods_table_list($link) {

    // SQL生成
    $sql = 'SELECT goods_name, price FROM goods_table';

    // クエリ実行
    return get_as_array($link, $sql);

}
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>商品一覧</title>
    <style type="text/css">
        table, td, th {
            border: solid black 1px;
        }
        table {
            width: 200px;
        }
        caption {
            text-align: left;
        }
    </style>
</head>
<body>
    <table>
    <caption>商品一覧(税込み)</caption>
        <tr>
            <th>商品名</th>
            <th>価格</th>
        <tr>
<?php foreach ($goods_data as $value) { ?>
        <tr>
            <td><?php print $value['goods_name']; ?></td>
            <td><?php print $value['price']; ?></td>
        </tr>
<?php } ?>
    </table>

</body>
</html>
<?php

// 設定ファイル読み込み
require_once 'const.php';
// 関数ファイル読み込み
require_once 'model.php';

$goods_data = array();

// DB接続
$link = get_db_connect();

// 商品の一覧を取得
$goods_data = get_goods_table_list($link);

// DB切断
close_db_connect($link);

// 商品の値段を税込みに変換
$goods_data = price_before_tax_assoc_array($goods_data);

// 特殊文字をHTMLエンティティに変換
$goods_data = entity_assoc_array($goods_data);

// 商品一覧テンプレートファイル読み込み
include_once 'view.php';

※const.phpは設定ファイルでMVCモデルとは関係しません

controller.phpへアクセスするとfunc_sample.phpと同じく商品一覧が表示されます。

php-mvc2-639

require_onceとinclude_onceは、それぞれ指定されたファイルを読み込みます。

// 設定ファイル読み込み
require_once 'const.php';
// 関数ファイル読み込み
require_once 'model.php';
// 商品一覧テンプレートファイル読み込み
include_once 'view.php';

fgets関数などによるファイル読み込みは「ファイルの中身を文字列として取得」でしたが、require_onceとinclude_onceは「読み込んだファイルを合体させて1つのファイルとみなす」ようなイメージです。

これにより、4つに分割したファイルを1つにしています。

require_onceと include_onceの違いは以下となります。

require_once ファイル読み込みに失敗するとエラーが発生して処理が停止する include_once ファイル読み込みに失敗しても警告はあるが処理は停止しない

基本的にはrequire_onceを利用しますが、View(HTML)の場合は処理が停止してしまうとブラウザに何も表示されなくなるため、include_onceを利用します。

今回作成した商品一覧ページに関して、「Model」「View」「Controller」それぞれの役割と処理の流れを図に示すと、以下のようになります。

php-mvc3-639

まずはControllerがユーザからのリクエスト(URLにアクセス)を受け取ります。次にControllerはリクエストに対し必要な処理をModelへ依頼し、Modelは処理を行いその結果を返します。

必要な処理が終わったら、ControllerViewへユーザへ表示するHTML内容を依頼し、Viewが表示内容を返します。

NEXT LESSON ☛ MVCモデル②~MVCの利点

PREV LESSON ☛ ユーザー定義関数②

Tech 2 GO編集部
ライター
Tech 2 GO編集部

関連記事