PHPでファイルを分ける(最小MVC風)

前回の php-db07 では、検索・追加・更新・削除を1ファイルにまとめていましたが、今後ログイン機能などを追加していくため、処理の見通しをよくする必要があります。この php-db08 では、最小構成のMVC風にファイルを分割し、役割ごとに整理された開発スタイルを学びます。

フォルダとファイル名

php-db08/
├── index.php       ← コントローラー(処理分岐、結果を変数にまとめてViewへ渡す)
├── db_connect.php  ← データベース接続処理
├── functions.php   ← 共通関数(バリデーションなど)
├── view.php        ← ビュー HTML表示専用(変数を埋め込むだけ)
├── style.css       ← CSS 見た目

db_connect.php

PDOを使ったデータベース接続専用ファイルです。DB接続に失敗した場合はエラーメッセージを表示して終了します。

<?php
$dsn = 'mysql:host=localhost;dbname=testdb;charset=utf8mb4';
$user = 'root';
$password = '';

try {
    $pdo = new PDO($dsn, $user, $password);
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
    echo "DB接続エラー:" . $e->getMessage();
    exit;
}

functions.php

共通処理をまとめたファイルです。今後他のページでも使える関数を集約します。

<?php
// HTMLエスケープ
function h($str) {
    return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

// 空チェック
function is_not_empty($value) {
    return trim($value) !== '';
}

// メール形式チェック
function is_valid_email($email) {
    return filter_var($email, FILTER_VALIDATE_EMAIL) !== false;
}

index.php(Controller)

フォームからの送信内容に応じて検索・追加・更新・削除の処理を行います。最後に view.php を読み込んで、変数を渡して画面を表示します。

※全文は省略していますが、冒頭と最後の流れは以下の通りです

<?php
require_once 'db_connect.php'; // データベース接続
require_once 'functions.php';  // 共通関数など

$msg = '';
$searchKeyword = '';
$rows = [];

// 検索処理(GET)
// 追加処理(POST)
// 更新処理(POST)
// 削除処理(POST)

include_once 'view.php'; // 最後にHTMLを出力

view.php

index.php で準備された $msg, $rows, $searchKeyword などの変数を受け取り、画面に表示するHTMLテンプレートです。ここにはロジックは一切書かず、表示に集中させます。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>ユーザー管理</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>

<h1>ユーザー管理</h1>

<div class="reset">
    <a href="index.php">データを変更したら画面を更新してください</a>
</div>

<?php if ($msg): ?>
    <p><strong><?= h($msg) ?></strong></p>
<?php endif; ?>

<!-- 検索フォーム -->
<form method="get">
    <input type="text" name="keyword" placeholder="名前やメールで検索" value="<?= h($searchKeyword) ?>">
    <button type="submit">検索</button>
</form>

<!-- 一覧表示 -->
<table>
    <tr>
        <th>ID</th>
        <th>名前</th>
        <th>メール</th>
        <th>登録日時</th>
    </tr>
    <?php foreach ($rows as $row): ?>
        <tr>
            <td><?= h($row['id']) ?></td>
            <td><?= h($row['name']) ?></td>
            <td><?= h($row['email']) ?></td>
            <td><?= h($row['created_at']) ?></td>
        </tr>
    <?php endforeach; ?>
</table>

<!-- 追加フォーム -->
<h2>ユーザー追加</h2>
<form method="post">
    <input type="hidden" name="action" value="add">
    <label>名前:<input type="text" name="name" required></label><br>
    <label>メール:<input type="email" name="email" required></label><br>
    <button type="submit">追加する</button>
</form>

<!-- 更新フォーム -->
<h2>ユーザー更新</h2>
<form method="post">
    <input type="hidden" name="action" value="update">
    <label>ID:<input type="number" name="id" required></label><br>
    <label>名前:<input type="text" name="name" required></label><br>
    <label>メール:<input type="email" name="email" required></label><br>
    <button type="submit">更新する</button>
</form>

<!-- 削除フォーム -->
<h2>ユーザー削除</h2>
<form method="post">
    <input type="hidden" name="action" value="delete">
    <label>ID:<input type="number" name="id" required></label><br>
    <button type="submit">削除する</button>
</form>

</body>
</html>

style.css

画面全体の見た目を整えるスタイルシートファイルです。view.php で <link rel="stylesheet" href="style.css"> として読み込みます。

body {
    font-family: sans-serif;
    padding: 1em;
}

table {
    border-collapse: collapse;
    margin-bottom: 2em;
}

th, td {
    border: 1px solid #ccc;
    padding: .5em 1em;
}

form {
    margin-bottom: 2em;
}

.reset {
    background-color: #76d1ff;
    width: 350px;
    padding: 1rem;
    margin-bottom: 1rem;
    text-align: center;
}
  • 処理(ロジック)と表示(HTML)を分けることで保守しやすくなる
  • 再利用できるコードは関数化し、functions.phpにまとめて管理
  • 今後「ログイン機能」や「ページ分割」などを実装する際にもスムーズに拡張できる構成