シンプル&パワフルなPHPライブラリ rhacoを使ってみよう!

第4回rhacoアプリの基礎 Flow を学ぶ

前回までで、基本的なアプリケーションの土台はほぼ完成しました。今回は、rhacoを用いたアプリケーション開発の基本となる Flow という機構をつかって、ToDoデータの一覧画面を実際に構築してみます。

Flow とは

ウェブアプリケーションでは、ユーザーからのリクエストを受けてリクエストに見合った出力(HTML)を返すまでが一連の動作となりますが、rhacoでは基本的にそれぞれをリクエストクラス(network.http.Request⁠⁠、テンプレートクラス(tag.HtmlParser)として扱います。

しかし、これらは一般的にはいつもセットで使われるので、それらを統合したクラスが提供されています。それが、今回のメインとなる Flow(generic.Flow)です。

簡単な使用方法

まずは簡単な例をお見せします。

アプリケーションのディレクトリに hello.php として、次のようなファイルを作成してみましょう。

<?php
require_once '__init__.php';
Rhaco::import('generic.Flow');

$flow = new Flow();
// greeting に "Hello!" をセット
$flow->setVariable('greeting', 'Hello!');
if(!$flow->isVariable('name')){
    // name が与えられなかったら Guest をセット
    $flow->setVariable('name', 'Guest');
}
$flow->write('hello.html');

ここでは、Flowのみを使って、テンプレートの出力まで行っています。

最初の行の __init__.php で、アプリケーションの初期化を行います。__init__.php 内部で __settings__.php を読み込んでいるので、セットアップアプリケーションで設定した値などの読み込みや、rhaco本体の読み込みなどを行います。Rhaco::import については第1回でも利用しましたね。

このコードでは、 http://localhost/kaeru/hello.php に、⁠?name=なまえ」とクエリパラメータを与えると、出力も変わるようにしています。

画像

テンプレートファイルは、アプリケーションのディレクトリ内 resources/templates に設置します。セットアップアプリケーションから、テンプレートのディレクトリを変更することもできます。

ここでは、resources/templates/hello.html として、次のようなファイルを作成しました。

<html><body>
<h1>Greeting Sample</h1>

{$greeting} {$name}

</body></html>

これは、RequestとHtmlParserを使った次のようなコードとほぼ同じ意味を持ちます。

<?php
require_once '__init__.php';
Rhaco::import('network.http.Request');
Rhaco::import('tag.HtmlParser');

$request = new Request();
$parser = new HtmlParser();
// テンプレート変数 greeting に "Hello!" をセット
$parser->setVariable('greeting', 'Hello!');
$parser->setVariable('name', $request->getVariable('name', 'Guest'));
$parser->write('hello.html');

前述したコードと少し違う点にお気づきでしょうか?

getVariableメソッドに第二引数を渡すと、その値をデフォルトの値として扱うことができます。これを利用すると最初のコードももっと簡潔に書けそうですね。

それでは、実際にDBからToDo一覧を取得して表示するFlowを作成してみましょう。

DBに接続をする

第3回「データベースの設定と作成」で既にDBの準備はOKですね。

アプリケーション内でDBに接続するには DbUtil(database.DbUtil)というクラスを利用します。

DB設定は projext.xml の各databaseによって接続先が変わることも考えられるので、テーブルモデルクラスを利用してDbUtilへ接続情報を与えます。

テーブルモデルは、library/model に生成されています。Rhaco::import は、rhaco内部のライブラリだけではなく、アプリケーションのlibrary以下のファイルを読み込むときにも使用します。

<?php
require_once '__init__.php';
Rhaco::import('database.DbUtil');
Rhaco::import('model.Todo');

// DbUtil に、Todoモデルクラスの connection メソッドの返り値を渡す
$db = new DbUtil(Todo::connection());

これで、DBへの接続は完了です。

一覧画面を出力してみる

Flow, DbUtil を組み合わせて、DBから取得したToDoをHTMLで一覧にしてみます。

次のようなコードになります。

flow.php
<?php
require_once '__init__.php';
Rhaco::import('database.DbUtil');
Rhaco::import('model.Todo');
Rhaco::import('generic.Flow');

$db = new DbUtil(Todo::connection());
$flow = new Flow();
$flow->setVariable('object_list', $db->select(new Todo()));
$flow->write('list.html');

DbUtilのselectメソッドには、取得したいテーブルのモデルインスタンスを与えます。返り値はモデルオブジェクトの配列となります。つまり、object_list には配列型がセットされます。これをテンプレートでループして一覧を実現します。

DBの操作も、ごく簡単な操作だけで行えることがわかってもらえると思います。

テンプレートは次のようなものになります。あまりにも殺風景だったので、簡単なCSSを追加しているので少し冗長に見えますが、一覧に関係しているのは table の部分のみです。

resources/templates/list.html
<html>
<head>
  <meta http-equiv="Content-Type" content="application/xhtml+xml; charset=utf-8" />
  <title>kaeru :: todo manager on rhaco</title>
  <style type="text/css">
    table#todo th, table#todo td {
      padding: .3em;
    }
    table#todo th {
      background: #aaa;
    }
    table#todo tr.odd {
      background: #dcdcdc;
    }
  </style>
</head>
<body>
  <h1>todo manager</h1>
  <h2>list</h2>
  
  <table id="todo" rt:param="object_list" rt:var="object">
    <tbody>
      <tr class="even">
        <td>{$object.subject}</td>
        <td>{$f.text2html($object.description)}</td>
        <td>{$object.captionPriority()}</td>
      </tr>
    </tbody>
    <thead>
      <tr>
        <th>subject</th>
        <th>description</th>
        <th>priority</th>
      </tr>
    </thead>
  </table>
</body>
</html>

今回使用したテンプレートの記法について解説します。

rt:param, rt:var

ループさせたい table, ul, select の属性として指定します。param には変数名、var にはループ内で用いる変数を設定します。

tableで利用する場合、tbodyがあるとその内部についてのみループします。また、class要素に⁠even⁠または⁠odd⁠を指定すると、ループ内で even/odd が交互に出力されます。

{$f.text2html()}

テンプレートの予約変数 $f は、tag.model.TemplateFormatter に存在します。

text2htmlメソッドは、文字列をエスケープしたあと、改行に <br /> を追加します。引数を設定すると文字数や行数の制限も可能です。

flow.php にアクセスして一覧が表示されているのを確認してみましょう。

画像

これで今回の目標達成です。お疲れ様でした。

管理画面から、ToDoを追加したり削除したりして一覧が更新されるか試してみるのもよいでしょう。

次回予定は、Flow+DBをもっと簡単にするViewsという仕組みで一覧から、追加までを実装していきます。

おすすめ記事

記事・ニュース一覧