前回解説したViewsをつかうと,簡単なアプリケーションの作成ならばメソッド一つで実現できるようになりました。
今回は,ViewsとUrlsを組み合わせて,URLを自在に設計してみます。また,まとめとして今まで開発してきたすべてのソースのリポジトリを作成してみました。
Urlsとは
CakePHPなど,最近のフレームワークでは標準で搭載されている「Cool URI」と呼ばれるようなURI設計を可能にするライブラリです。
正規表現を使って,自由自在にURLの設計ができるようになります。
Urlsをつかう
使い方は非常に簡単です。Urlsクラスのparserメソッドに,URLマッピングの配列を引数として渡すと,UrlsがURLを解析して該当するアクションを実行し,HtmlParserのインスタンスを返却します。
使用例
ここでは,TodoモデルのCRUDを実現する簡単な定義を紹介します。
index.php
<?php
require_once '__init__.php';
Rhaco::import('generic.Urls');
Rhaco::import('model.Todo');
$patterns = array(
// リスト
'^$' => array(
'class' => 'generic.Views',
'method' => 'read',
'args' => array(new Todo(), new C(Q::eq(Todo::columnClose(), false))),
'template' => 'list.html',
),
// generic.Views を使用する場合は,設定を省略できます。
'^detail/(\d+)$' => array('method' => 'detail', 'args' => array(new Todo(), new C(Q::fact()))),
'^create$' => array('method' => 'create', 'args' => array(new Todo(), null, Rhaco::url())),
'^update/(\d+)$' => array('method' => 'update', 'args' => array(new Todo(), null, Rhaco::url())),
'^delete/(\d+)$' => array('method' => 'delete', 'args' => array(new Todo(), null, Rhaco::url())),
);
$parser = Urls::parser($patterns);
$parser->write();
Urlsで指定できる値は次の通りです。
| 値 | 意味 |
|---|---|
| class | 実行するメソッドを持つクラス |
| method | 実行するメソッド名 |
| args | メソッドに渡す引数 |
| template | テンプレート名 |
| var | 追加でテンプレートにセットする値 |
この状態でindex.phpにアクセスすると,PATH_INFOに何もセットされていないので一番最初に定義した‘^$’の部分にマッチし,一覧画面が表示されます。
つぎに,Apacheの場合はmod_rewriteの設定を行います。mod_rewriteに関しては,rhacoのセットアップにて設定を自動で書き出すことができます。
setup/project.xmlの最初の行を次のように書き換えます。
変更前
<project rhacover="1.6.1" version="0.0.1" name="kaeru" ...
変更後
<project rhacover="1.6.1" version="0.0.1" name="kaeru" pathinfo="index.php" ...
変更後,setup.phpにアクセスすると初期処理を実行するボタンが出現します。
このボタンをクリックすると,アプリケーションのルートパス上にmod_rewriteの設定が記述された以下のような.htaccessが出力されます。
.htaccess
RewriteEngine On
RewriteBase /kaeru/
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.+)$ index.php?%{QUERY_STRING}&pathinfo=$1 [L]
完了ボタンを作成する
作成したTODOを完了するためには,本来であれば専用のクラスとメソッドを作ってアクションを実現することになりますが,ここでは少し工夫してUrls+Viewsの機能だけで完了のアクションを作成してみます。
先に述べたUrlsの指定にupdateの項目が既にあるので,強引ですがテンプレートの変更で対応します。
resources/templates/list.html(変更点のみ)
<table id="todo" rt:param="object_list" rt:var="object">
<tbody>
<tr class="even">
<td>{$object.factCategory.toString()}</td>
<td><a href="{$rhaco.url('detail')}/{$object.id}">{$object.subject}</a></td>
<td>{$f.text2html($object.description)}</td>
<td>{$object.captionPriority()}</td>
<form action="{$rhaco.url('update')}/{$object.id}" method="post">
<td>
<input type="hidden" name="category" value="{$object.category}" />
<input type="hidden" name="subject" value="{$object.subject}" />
<input type="hidden" name="description" value="{$object.description}" />
<input type="hidden" name="priority" value="{$object.priority}" />
<input type="hidden" name="close" value="1" />
<input type="submit" value="完了" />
</td>
</form>
</tr>
</tbody>
このように,http://localhost/kaeru/update に対して,closeフラグを強制的に1(true)にしてカラムを更新させると,一覧に表示されないようになります。

