0Pricing
PHP Academy · レッスン

テンプレートパターン:ロジックとビューの分離

ビジネスロジックをPHPファイルに移し、HTMLテンプレートをシンプルに保ちます

「テンプレートパターン:ロジックとビューの分離」はCoddyKit上の無料PHP Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはPHP Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 PHP Academyコースには全4レッスンが含まれています。

ロジックとビューを分離する理由

同じファイルにデータベースクエリ、ビジネスロジック、HTML を混在させると、次の問題につながります。

  • 読みにくいスパゲッティコードになる
  • ロジックのテストや再利用が難しくなる
  • 検証を省略した場合にセキュリティ上のミスが発生する

解決策は、それぞれの関心事を独自のレイヤーに分けることです。

シンプルなテンプレートパターン

最初にすべての PHP ロジックを実行し、その後で HTML を出力します。

<?php
// --- LOGIC (top) ---
require 'config.php';
$userId = (int) ($_GET['id'] ?? 0);
$user   = getUserById($userId);
if (!$user) {
    http_response_code(404);
    require '404.php';
    exit;
}
$pageTitle = 'Profile: ' . $user['name'];

// --- VIEW (bottom) ---
require 'layout/header.php';
?>
<main>
    <h1><?= htmlspecialchars($user['name']) ?></h1>
</main>
<?php require 'layout/footer.php'; ?>

コントローラーとビューファイルの分離

コントローラーファイルとビューファイルに分割します。

// profile.php (controller)
<?php
require 'config.php';
$userId = (int) ($_GET['id'] ?? 0);
$user   = getUserById($userId);
$posts  = getPostsByUser($userId);

if (!$user) { require '404.php'; exit; }

require 'views/profile.view.php';

// views/profile.view.php (view) — only HTML and echoes
// No DB calls allowed here!

ビュー用データの準備

ビューに渡す前に、ロジックレイヤーですべてのデータをフォーマットします。

<?php
$user = getUserById($id);

$viewData = [
    'userName'   => htmlspecialchars($user['name']),
    'avatarUrl'  => $user['avatar'] ?? '/default.png',
    'joinedDate' => date('F Y', strtotime($user['created_at'])),
    'isAdmin'    => in_array('admin', $user['roles']),
];

extract($viewData);  // Makes $userName, $avatarUrl, etc.
require 'views/profile.view.php';

テンプレート関数パターン

ビューのレンダリングを関数でラップして、再利用しやすくします。

<?php
function render(string $view, array $data = []): void {
    extract($data);  // Create variables from array
    require __DIR__ . '/views/' . $view . '.php';
}

// Usage:
render('profile', [
    'name'   => $user['name'],
    'email'  => $user['email'],
]);

出力バッファリングによるテンプレートエンジン

テンプレートをレンダリングし、文字列として返します。

<?php
function renderToString(string $view, array $data = []): string {
    extract($data);
    ob_start();
    require __DIR__ . '/views/' . $view . '.php';
    return ob_get_clean();
}

$html = renderToString('email/welcome', ['name' => 'Alice']);
mail($to, 'Welcome!', $html, 'Content-Type: text/html');

テンプレートエンジンを使用するタイミング

シンプルなサイトでは、PHP のネイティブテンプレートで十分です。次のような場合は Twig や Blade を検討してください。

  • デフォルトで自動エスケープを行いたい
  • デザイナーが PHP の知識なしでテンプレートを編集する必要がある
  • テンプレートの継承やマクロが必要である
  • ビューが多く、プロジェクトの規模が大きくなる

Twig の例

Symfony で使用される Twig は、自動エスケープに対応したすっきりした構文を提供します。

<?php
// After: composer require twig/twig
$loader = new Twig\Loader\FilesystemLoader('/templates');
$twig   = new Twig\Environment($loader, ['cache' => '/tmp/twig']);

echo $twig->render('profile.html.twig', [
    'user'  => $user,
    'posts' => $posts,
]);

// profile.html.twig:
// <h1>{{ user.name }}</h1>  -- auto-escaped by default

MVC のディレクトリ構成

プレーンな PHP プロジェクト向けの最小限の MVC 構成です。

project/
  controllers/
    UserController.php   -- handles request, calls model
  models/
    User.php             -- database queries
  views/
    users/
      profile.php        -- display only, no logic
  public/
    index.php            -- front controller (router)

フロントコントローラーパターン

すべてのリクエストを単一のエントリポイント経由でルーティングします。

<?php
// public/index.php (front controller)
require __DIR__ . '/../vendor/autoload.php';

$uri    = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$routes = require '../routes.php';

if (isset($routes[$uri])) {
    [$controller, $action] = $routes[$uri];
    (new $controller)->$action();
} else {
    http_response_code(404);
    require '../views/404.php';
}

単一責任の原則

各ファイルには、変更する理由を 1 つだけ持たせるべきです。

  • Model: データ構造またはクエリロジックが変わる場合だけ変更する
  • Controller: リクエスト処理ロジックが変わる場合だけ変更する
  • View: UI またはレイアウトが変わる場合だけ変更する

これにより、それぞれの部分を独立してテストおよび保守しやすくなります。

確認問題

PHP のロジックを HTML のビューコードから分離する主なメリットは何ですか。

まとめ: テンプレートパターン

重要なポイント:

  • 最初にすべてのロジックを実行し、その後で HTML を出力する
  • コントローラーとビューファイルに分離する
  • extract() を使用した render() 関数を使う
  • 出力バッファリングでレンダリング済み HTML を取得する
  • 大規模なプロジェクトでは Twig/Blade を検討する
  • フロントコントローラーですべてのリクエストをハンドラーにルーティングする

よくある質問

「テンプレートパターン:ロジックとビューの分離」レッスンは無料ですか?

はい。「テンプレートパターン:ロジックとビューの分離」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、PHP Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 PHP Academyコースには全4レッスンが含まれています。

「テンプレートパターン:ロジックとビューの分離」で何を学びますか?

ビジネスロジックをPHPファイルに移し、HTMLテンプレートをシンプルに保ちます ブラウザで直接実行するハンズオンコードでPHP Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

PHP Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのPHP Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「テンプレートパターン:ロジックとビューの分離」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このPHP Academyレッスンでコードを書いて実行できますか?

はい。すべてのPHP Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. PHPタグと埋め込み構文
  2. PHPループで動的なHTMLを生成する
  3. ファイルのインクルードと読み込み
  4. テンプレートパターン:ロジックとビューの分離
← PHP Academyに戻る