[PHP]Slim FrameworkでPhpRenderを利用したViewコンポーネントの分離を行う

カテゴリ: SlimFramework

PHPのマイクロフレームワークでであるSlim Frameworkでは、標準ではViewに相当するコンポーネントが用意されていません。マイクロなだけに、ルーティング処理中でViewの出力まで行っても良いのですが、最低限のMVCによるViewの分離ぐらいは行いたい場合が多いです。

このような場合、slimのPhpRender(php-viewパッケージ)を利用することで、素のPHPファイルをテンプレートにしつつ、Viewを別ファイルに分離することができます。

php-viewコンポーネントのインストール

PhpRenderの機能は、slim/php-viewパッケージとして提供されており、composerでインストール出来ます。PhpRenderのパッケージはSlim Framework本体とは別で管理されているため、以下のようにそれぞれインストールします。

composer require slim/slim
composer require slim/php-view

まずは、Slim Frameworkのサンプルコードを実行

php-viewを使わないパターンでのコードを元にして、少しづつ改良を進めていきます。

こちらは、Slim Frameworkに記載されているコードです。

<?php
use \Psr\Http\Message\ServerRequestInterface as Request;
use \Psr\Http\Message\ResponseInterface as Response;

require 'vendor/autoload.php';

$app = new \Slim\App;
$app->get('/hello/{name}', function (Request $request, Response $response) {
    $name = $request->getAttribute('name');
    $response->getBody()->write("Hello, $name");

    return $response;
});
$app->run();

上記のファイルをindex.phpとして保存し、下記のコマンドで実行します。

php -S localhost:80 index.php

その後、ブラウザからhttp://localhost/hello/aliceにアクセスして、"Hello, alice"の出力されることを確認します。このコードをベースに、PhpRenderパッケージを導入します。

PhpRenderを使う

それでは、PhpRendererを使ったコードに書き換えていきます。

先ほどのコードは、PhpRendererによって以下の様に書くことができます。

// PhpRendererを使用してViewを出力(DIコンテナ未使用)
$app->get('/hello/{name}', function (Request $request, Response $response) {
    $renderer = new \Slim\Views\PhpRenderer("./view");

    // Viewに渡すパラメータをセット
    $viewParam = [
        'name' => $request->getAttribute('name'),
    ];

    // Viewの描画
    return $renderer->render($response, 'hello/index.tpl', $viewParam);
});

出力処理だった"Hello, $name"に相当する部分がなくなっており、替わりにhello/index.tplというViewの読み込み処理が追加されています。

viewに相当するファイルは、/view/hello/index.tplに別で管理します。

# view/hello/index.tpl
Hello, <?=$name?>

このプログラムを実行すると、最初のプログラムと同じく"Hello, alice."と出力されます。

PhpRendererのコンストラクタでは、viewのファイルを管理するベースディレクトリを指定します。その後、\Slim\Views\PhpRenderer::render()でresponseオブジェクトと、テンプレートを渡せば、結果のhtmlが出力されたresponseとして返されるので、returnすればよいです。

ControllerからViewに渡すパラメータがある場合は、連想配列を用意してrender()の第三引数にセットします。viewでは連想配列のキーが変数名として参照できます。

リクエストのパラメータをそのまま渡す

ルーティングで渡されるパラメータ(URL指定で記述した'/hello/{name}'のnameに該当する部分)は、クロージャーの第三引数で受け取れます。

このため、以下の様に書くとViewへの受け渡しパラメータを別途用意する必要がなくなります。これは、{name}に相当する情報が$args['name']に保存されているためです。

$app->get('/hello/{name}', function (Request $request, Response $response, $args) {
    $renderer = new \Slim\Views\PhpRenderer("./view");

    return $renderer->render($response, 'hello/index.tpl', $args);
});

ViewRendererをDIコンテナで管理する

Slim FrameworkのViewRendererですが、PhpRenderer以外にもSmartyやTwigをベースにした物が複数用意されています。

このため、上記のコードのようにコントローラー側で直接\Slim\Views\PhpRendererクラスを生成していると、将来Viewのレンダラーを変えたいときに、コントローラのロジックを修正する必要があります。

$renderer = new \Slim\Views\PhpRenderer("./view");
↓
$renderer = new \Slim\Views\SmartyRenderer("./view");

これを避けるためには、DIコンテナを利用するとよいです。
以下のようにDIコンテナにViewのRendererを登録したうえで...

// ViewレンダラをDIコンテナに登録
$app = new \Slim\App;
$container = $app->getContainer();
$container['renderer'] = function ($c) {
    return new \Slim\Views\PhpRenderer("./view")
};

コントローラー側では、以下のように$this->rendererで、DIコンテナに登録されたRendererを取得します。

// DIコンテナに登録されたレンダラで出力する
$app->get('/hello/{name}', function (Request $request, Response $response, $args) {
    return $this->renderer->render($response, 'hello/index.tpl', $args);
});

こうしておくと、将来Viewレンダラーを変更したい場合に以下のようにDIコンテナへの登録処理だけ差し替えればよくなります。

// ViewレンダラとしてPhpRendererを使用
$container['renderer'] = function ($c) {
    return new \Slim\Views\PhpRenderer("./view");
};

// ViewレンダラとしてSmartyを使用
$container['renderer'] = function ($c) {
    return new Slim\Views\Smarty()
};

Amazonでおトクに買い物する方法
AmazonチャージでポイントGET


Amazonは買いもの前にAmazonギフト券をチャージしてポイントをゲットしないと損!

こちらもおススメ

コメントを残す

メールアドレスが公開されることはありません。