読者です 読者をやめる 読者になる 読者になる

Piece Frameworkを導入する

PHP

Piece Frameworkを使って簡単なWebアプリケーションを作ってみたいと思います。
まずはおなじみのHello Worldです。

インストール

公式ページのドキュメントに従ってインストールします。

pear channel-discover pear.hatotech.org
pear install hatotech/Piece_Unity-beta

Piece_Unityに付属するサンプルを動かすためには、Piece_RightとHTML_Template_Flexyが必要です。これらも一応インストールしておきます。

pear install hatotech/Piece_Right
pear install HTML_Template_Flexy

またPiece Frameworkはyamlを至る所で使用しています。
spycのサイトから最新版のspyc.phpをダウンロードしてください。

プロジェクトを作成

今回は次のような構成でディレクトリを作りました。

- actions
- templates
- templates_c
- cache
- config
   - piece-unity-config.yaml
- lib
   - spyc.php
- www
   - index.php

ダウンロードしたspyc.phpをlibディレクトリに配置し、index.phpの中でinclude_pathにこのlibディレクトリを追加することにしました。


続いて、configディレクトリにpiece-unity-config.yamlを作ります。
現在のバージョンでサポートしているのはyaml形式だけのようで、ファイル名はpiece-unity-config.yamlで固定のようです。


Piece Frameworkのディスパッチャーには、要求に対する応答を返すだけの「状態を持たない」Dispatcher_Simpleと、「状態をもつ」Dispatcher_Continuationがあります。今回のアプリは要求に対して、Hello Worldと返すだけなので、Dispatcher_Simpleを使用します。
Piece Frameworkは、ビューにHTML_Template_Flexy, Smarty等をサポートしていますが、公式サンプルとの違いを持たせるために、今回はSmartyを使うことにしました。


以上の条件から、piece-unity-config.yamlを次の様に記述します。

- name: Controller
  point:
    - name: dispatcher
      type: extension
      value: Dispatcher_Simple
    - name: view
      type: extension
      value: View
- name: Dispatcher_Simple
  point:
    - name: actionDirectory
      type: configuration
      value: ../actions
- name: View
  point:
    - name: renderer
      type: extension
      value: Renderer_Smarty  # (A)
- name: Renderer_Smarty
  point:
    - name: template_dir
      type: configuration
      value: ../templates     # (B)
    - name: compile_dir
      type: configuration
      value: ../templates_c   # (C)
    - name: cache_dir
      type: configuration
      value: ../cache         # (D)

(A)でビューにSmartyを使う(Render_Smartyを使う)ことを宣言し、(B)、(C)、(D)で、それぞれ、Smartyのtemplate_dir, compile_dir, cache_dirを設定しています。


YAMLの構文エラーがあったり、スペルミスがあると、設定が正しく反映されません。
さらに、Piece_Unityは内部では出力バッファリングを行っているため、設定が間違っていても、ブラウザの画面にエラーや警告は一切表示されません。
個人的にはここがPiece Frameworkの最初の落とし穴のように感じます。


Piece Frameworkでは、PHPの警告やエラーはサーバのエラーログ(例えば、ApacheならばApacheホームディレクトリのlog/error_log)に記録されて、Piece Framework内部でのエラーは、Piece_Unity_Errorがエラーを記録し、PEAR_Errorの流儀でグローバル変数にスタックされています。
この点を認識しておかないと、何が原因で動かないのか延々と悩む羽目になります。
始めのうちは、index.php

...

$unity =& new Piece_Unity($config, $cache, null);
$unity->dispatch();
if (Piece_Unity_Error::hasErrors()) {
	print_r(Piece_Unity_Error::pop());
}

...

のようにエラーを出力するようにすると、何が原因で動作しないのか簡単に分かるようになります。

ビューを記述する

設定が完了したら、次にビューを記述します。templatesディレクトリの下にIndex.tplを作ります。

- templates
   - Index.tpl

Index.tplの中身です。

<html>
<head><title>Hello World</title></head>
<body>
<h1>Hello World</h1>
{if $currenttime}
<p>the current time is {$currenttime}</p>
{/if}
</body>
</html>

これだけでもう静的なページを表示することができるはずです。サーバを起動し、
index.phpに_event=Indexというパラメタを与えてアクセスしてみましょう。

http://localhost/your/wwww/index.php?_event=Index

Hello Worldというメッセージが表示されたでしょうか?
続いて、templatesディレクトリにHelloというディレクトリを作り、その中にPiece.tplというファイルを追加してみます。

- templates
   - Index.tpl
   - Hello
        - Piece.tpl

Piece.tplの内容です。

<html>
<head><title>Hello Piece_Unity</title></head>
<body>
<h1>Hello Piece_Unity</h1>
</body>
</html>

このページを表示するには、

http://localhost/your/wwww/index.php?_event=Hello_Piece

にアクセスします。


Dispatcher_Simpleは要求されたイベントの名称から、対応するビューを探します。
このときイベント名の_(アンダースコア)は/(スラッシュ)に変換されるので、Hello_Pieceというイベントに対応するのビューは、Hello/Pieceになります。
大小文字の変換はおこなわれません。Windows/Mac OS Xで開発し、Linuxサーバで運用というようなプロジェクトでは注意が必要でしょう。

アクションを記述する

続いて、Indexイベントが発生した時に実行されるアクションを記述します。Dispatcher_Simpleを使っている場合は、特別なクラスを継承する必要はありませんが、クラス名は「イベント名Action」とし、必ずinvokeメッソドを実装するようにしてください。

アクションクラスのディレクトリ構造、ファイル名は

-actions
   IndexAction.php
   -Hello
       PieceAction.php

のようにします。ファイル名の接尾辞をXXXXAction.phpとしなくてはなりません。テンプレートと同様に、アンダースコアはディレクトリに置き換えられます。


Viewに値を渡す方法を確認するために、以下のようなアクションを記述しました。

getViewElement();
	    $e->setElement('currenttime', date('r')); 
    }
}
?>

これでSmartyにcurrenttimeという変数を渡すことができました。アクセスするたびに、サーバ側の現在時刻が表示されるはずです。
時刻の部分に何も表示されない場合は、アクションクラスが命名規則に従っているか、invokeメソッドを実装しているかどうかを確認してください。
Dispatcher_Simpleは、これらの規則に満たしていないアクションを無視して、ビューのレンダリング処理を行います。


このサンプルはここからダウンロードできます。


以上、Dispatcher_Simpleの使い方を紹介しました。今回作ったアプリケーションは何の役にも立ちませんが、実際にはDispatcher_Simpleだけで、MojaviEthnaと同等のことができると思います。