rhaco2を学習 その1
2010年01月12日(火) 00:51
- 環境:OSX 10.6.2
- setupにはOSX標準のPHP 5.3.0 (cli)を利用
- 動作環境: MAMP1.8.4のPHP5.2.11を利用
rhaco2をインストールして、ついでにサンプルアプリケーションも導入してみる。
rhaco2のインストールは簡単なんだけど、入力に関するメタ情報がないので補足します。
1.インストーラのダウンロード
まず、setup.phpというものをダウンロードします。これは本家のトップに書いてあるままで良いでしょう。
rhaco2作者がOSXを使っているため、OSXで簡単に入れられるようにcurlで取得するコマンドが書かれています。
curl -LO http://rhaco.googlecode.com/files/setup.php単にURLにブラウザにアクセスして持ってきてもかまいません。
2.インストーラの実行+サンプルアプリケーションのインストール
インストーラを実行しますが、rhaco2のインストールだけを行うという行為は見当たりません。
今から何かを作る、ないしはサンプルアプリのインストールを行うことが前提となっています。
サンプルアプリケーションを全部インストールし、かつ、rhaco2自体はひとつだけいれたいと思います。
2010/01/08の時点では、以下のサンプルアプリケーションがあるようです( http://rhaco.org/docs/app/rhaco.org に一覧がある)。
Sample Applications アプリケーションパス 説明 org.rhaco.sample.calc 簡単な計算アプリ。入力を受け取って、処理をしてテンプレートに出すサンプル。 org.rhaco.sample.hello_world 単にテンプレートをそのまま出力するサンプル。 org.rhaco.sample.hello_xml pathinfoというxmlでURLとflow(アクション的なもの)の関連付けをしているサンプル。XML出力のサンプルではない。 org.rhaco.sample.invoke 指定した処理とその出力を次の処理に渡していくアプリケーションのサンプル org.rhaco.sample.openid openidのサンプル org.rhaco.sample.parse_and_paginate Feed ParserとPaginaterのサンプル org.rhaco.sample.rtextends テンプレート継承のサンプル ここからは、以下のディレクトリ構成にする前提で記述します。
学習用ディレクトリ パス 目的 /Users/makoto/Code/rhaco2std 学習用ディレクトリ /Users/makoto/Code/rhaco2std/core rhaco2のcoreインストールディレクトリ /Users/makoto/Code/rhaco2std/apps MAMP-ApacheのDocumentルート /Users/makoto/Code/rhaco2std/apps/calc サンプル /Users/makoto/Code/rhaco2std/apps/hello_world サンプル /Users/makoto/Code/rhaco2std/apps/hello_xml サンプル /Users/makoto/Code/rhaco2std/apps/invoke サンプル /Users/makoto/Code/rhaco2std/apps/openid サンプル /Users/makoto/Code/rhaco2std/apps/parse_and_paginate サンプル /Users/makoto/Code/rhaco2std/apps/rtextends サンプル a.学習用ディレクトリとMAMP-Apacheのドキュメントルートディレクトリを作成し、MAMPのドキュメントルートを変更します(MAMP→環境設定→Apache→Document Root)。
b.サンプルディレクトリを作成し、各ディレクトリにsetup.phpをコピーします。
setup.phpのある場所を起点としようとする節があるので、すべてのサンプルディレクトリにコピーをします。c.サンプルをインストールします。
各サンプルアプリケーションのディレクトリで、setup.phpを実行します。
最初に聞かれるcoreの場所をrhaco2のcoreインストールディレクトリにします。あとは、変更なしでいいでしょう。
$ php setup.php -install org.rhaco.sample.calc core path[/Users/makoto/Code/rhaco2std/apps/calc/core/]: /Users/makoto/Code/rhaco2std/core install application: application url [http://localhost/calc]: working directory [/Users/makoto/Code/rhaco2std/apps/calc/work/]:インストールするサンプルアプリケーションを変更して、他のサンプルアプリケーションについても サンプルアプリケーションのディレクトリで 同様に実行します。
coreはもし指定したディレクトリに存在すれば二度目からはスルーされるようです。
3.インストールしたサンプルを実行してみる。
ブラウザで http://localhost:8888/ を開くと、サンプルアプリケーションのディレクトリが一覧されます(Apacheのディレクトリインデックスね)。
一覧をポチっとクリックすると各サンプルアプリケーションが実行されます。
続いてサンプルアプリケーションの中身を覗いてみます。
サンプルアプリケーションの中身を覗いてみる
org.rhaco.sample.calc
calcアプリケーションはこんなファイル構成です。
├── __settings__.php ├── index.php ├── resources │ └── templates │ └── display.html └── setup.php
index.php
アプリケーションのスクリプトですね。
require dirname(__FILE__)."/__settings__.php";
冒頭で同階層にある __settings__.php をrequireしています。
rhaco2の機能のみを使っているので、これ以外にはrequireしていませんね。 では、 __settings__.php をみてみましょう。
__settings__.php
このファイルには直にファイルパスが記述されています。 開発環境ごとに、また本番環境でも別のファイルとして必要ですので、構成管理の対象外にしておいた方が無難でしょう。
require_once("/Users/makoto/Code/rhaco2std/core/jump.php"); App::config_path(__FILE__,"http://localhost/calc/","/Users/makoto/Code/rhaco2std/apps/calc/work/");jump.php をrequireし、アプリケーションのルートパス(渡してるのはファイルパスですが、内部でディレクトリに変換されています)・アプリケーションの基点URLとワークディレクトリの情報をAppに設定しています。
このAppクラスはjump.phpで spl_autoload_register に登録している autoload_handler でフォールバックされているクラスです。 __settings__.php さえ読み込んでおけば、rhaco2の基本的なクラスは未定義で利用できます。
rhaco2のクラス実装を確認した場合には、 core/jump.php のswitch文からクラスファイルの場所をたどればよいでしょう。
続けてindex.phpを見ていきましょう。
$flow = new Flow(); $result = ""; if($flow->is_vars("calc")){ $arg1 = $flow->in_vars("arg1",0); $arg2 = $flow->in_vars("arg2",0); switch($flow->in_vars("calc")){ case "add": $result = $arg1 + $arg2; break; case "subtract": $result = $arg1 - $arg2; break; case "multiply": $result = $arg1 * $arg2; break; case "divide": $result = $arg1 / $arg2; break; } } $flow->vars("result",$result); $flow->output("display.html");このFLowを使うのが基本のようです。Request処理とResponse処理をまかないます。
$flow->is_vars は、リクエストに指定の名前で値が渡されているか確認します。
$flow->in_vars は、リクエストから同名で送信されてきた値を取り出します。第二引数はおそらくデフォルト値でしょう。
$flow->vars は、第一引数の名前で、第二引数の値をコンテキストに詰めます。
$flow->output は、指定のテンプレートをレンダリングして結果を出力します。 この時テンプレートファイルを探索するディレクトリは、base_template_pathがFlowにセットされていない場合には、 アプリケーションルート/resources/templates になるようです。
さらに display.html も見てしまいます。
<html> <body> <form rt:ref="true"> ARG1: <input type="text" name="arg1" /> ARG2: <input type="text" name="arg2" /> <input type="submit" name="calc" value="add" /> <input type="submit" name="calc" value="subtract" /> <input type="submit" name="calc" value="multiply" /> <input type="submit" name="calc" value="divide" /> <br/> <br/> <br/> <br/> <rt:if param="{$result}"> Result: {$t.html($result)} </rt:if> </form> </body> </html>formタグに rt:ref という見慣れないアトリビュートがあります。 rt: がrhaco2のテンプレートタグ機能のようです。このrt:refは、コンテキストに同名で値が入っていると自動フィルするための設定です。サンプルではformタグに設定されていますが、個別のinputタグに設定もできます。
rt:if でコンテキストにresultという名前で値が設定されているかを確認し、値があった場合には $t.html でエスケープして出力しています(出力は {$keyname} ですね)。
org.rhaco.sample.hello_xml
このサンプルは動作させるためにもうひと作業必要です。hello_xmlディレクトリに移動して次のコマンドを実行します。
$ php setup.php -write_htaccess hello_xml
hello_xmlの部分は、サンプルをインストールしたディレクトリ名にしています。
この作業を行うと、 .htaccess が生成されます。
.htaccess
RewriteEngine On RewriteBase /hello_xml RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.+)$ index.php/$1?%{QUERY_STRING} [L]hello_xmlは、RewriteBaseに使われていますね。今回のディレクトリ構成の場合は上記のようになるだけで、実際に開発する場合にはディレクトリ構成はいろいろなパターンが有るでしょう。
これで、 http://localhost:8888/hello_xml/hello でアクセス出来るようになります。
index.php
.htaccessでふられているindex.phpを見てみましょう。
<?php require dirname(__FILE__)."/__settings__.php"; app(); ?> <app name="hello" summary="pathinfoを使ったxmlのサンプル"> <description> http://〜/test へアクセスするとマッピングされた処理を実行します -write_htaccess [path]で.htaccessを作成できます </description> <handler> <map url="/hello" class="FlowSampleHello" method="hello" template="display.html" summary="ハローワールド" name="hello_world" /> </handler> </app>calcのindex.phpとはかなり違いますね。
__settings__.phpをrequireしたあと、 app(); が実行されています。
app()は、 core/__funcs__.php に定義されている関数で、引数 path があれば指定されたpathのファイルからアプリケーションのxmlを、今回のように引数がなければ実行されているファイル自信に記述されているアプリケーションXMLを Flowでloadします。
続く行はアプリケーションXMLと呼ばれるXMLです。今回は、/helloというURLで呼ばれた際にどの Flowを継承したクラス の メソッド を実行するかを定義しています。
このサンプルでは単純にべた書きのURLですが、実際には正規表現でURLの一部を実行するメソッドに渡したりできるはずです。
classに定義されているクラスは アプリケーションルート/lib ディレクトリの中にあります。クラスの中身は今まで見てきたものと代わりはないのでスルーします。
org.rhaco.sample.invoke
指定した処理を次々に実行していくサンプルです。簡単に言えばPlaggerを汎用的な考えにしたもの?でしょうか。このサンプルではフィードを対象にしていますが、処理の結果を次から次へと渡していくという概念のもののようです。
index.php
<?php require dirname(__FILE__)."/__settings__.php"; app(); ?> <app name="feed reader" summary="sample"> <invoke class="org.rhaco.net.xml.Feed" method="do_read"> <arg value="http://ameblo.jp/nakagawa-shoko/" /> <arg value="http://ameblo.jp/kurori1985/" /> </invoke> <invoke class="org.rhaco.net.xml.FeedConverter" method="strip_tags" /> <invoke method="output" /> </app>invoke タグでクラスと実行するメソッドを指定しています。同タグに arg タグがあり、対象のURLが設定されています。おそらく、ブログのURLからFeedを探し出して取ってくるクラスなのでしょう。
次のinvokeタグにはargの設定がありません。実際にFeedConverterクラスを確認してみると、AtomというFeedを抽象化したクラスのインスタンスを受け取るようになっています。きっと、一つ目のinvokeの結果がここに渡されてきますね。
最後のinvokeにはクラスさえ指定されていません。クラスの指定がない場合には、直前のinvokeの結果の型に対してmethod呼び出しが行われるようです。
org.rhaco.sample.parse_and_paginate(ページネータ) と org.rhaco.sample.rtextends(テンプレート継承)へ続く…と思う。
