アクションは、フレームワークが担当する共通の処理に含まれない個別処理を記述する部分です。 フレームワーク側はアクションを呼び出すだけで処理内容は定義していませんので、 処理内容はアプリケーションの開発ごとに作成する必要があります。
アプリケーション毎に作成するアクションは、共通の親クラスを継承します。 共通の親クラスにより、共通のアクション実行前/実行後メソッドを定義でき、 アクション実行前に透過的に行いたい処理の記述が可能です。
アクションは必須ではありません。 存在しなければ何も実行されないで、ビューに処理が移ります(ただし、親クラスに存在する共通のアクション実行前/実行後メソッドは実行されます)。
ここでは、そのアクションの作成方法を説明します。
※ここでは、pathinfoルーティングを例に扱います。
まず、アクションが起動されるまでの流れを示します。
読み込まれるアクションファイルは、URL(PATH_INFO)により決定されます。 例えば下記のようなURLにアクセスした場合、フロントコントローラにマッピングされたアプリケーション内の アクション、テンプレートが読み込まれます。
/example.php/example1/index.html ※ フロントコントローラ: /example.php ※ PATH_INFO: /example1/index.html
デフォルトで、
・アクションファイル
(アクションディレクトリ)/Example1/Index.php
・アクションクラス名
Example1_Index
・テンプレートファイル
(テンプレートディレクトリ)/Example1/Index.html
※ 各種先頭大文字
のようにマッピングされます。 (拡張子は、URL上は「.html」ですが、フレームワーク上では「.html」が「.php」に変換されたファイルがアクションファイルとなります。)
デフォルト以外の動作を行う場合は、「routers.xml」 を編集します。
例えば、下記のように編集すれば、アクションファイル「/Abc.php」に対するリクエストは、
「/Index.php」にフォワードされるようになります。
同様にテンプレートも「/Index.html」が読み込まれるようになります。
…
<router path="/Abc.php"
forwardAction="/Index.php"
forwardTemplate="/Index.html" />
…
※ path は正規表現の使用が可能です。
また、アクション内で動的にテンプレートを変更するには、下記のように記述します。
… function execute(&$data, &$context) { $context->setTemplateFile('/Index.html'); } …
actions.xml 設定ファイルは、アクションごとに自動でコンポーネントをインジェクションする場合に設定します。
… <action path="(.+)\.php" method="execute{action}"> <setter name="controller" direct="true"> <arg type="component" reference="true">controller</arg> </setter> </action> …
実行されるアクションファイルと、action の path が一致するディレクティブが処理されます。
ただし、マッピングが一致するアクションが必ず存在しなければなりません。(存在しない場合はエラーとなります)
よって、デフォルトの actions.xml は下記のように定義されています。設定を追加する場合は、この設定の上部に追加してください。
… <action path="(.+)\.php" method="execute{action}"> </action> …
アクションファイルのクラス名の命名規則は、 アクションディレクトリとアクションファイル(先頭大文字)を「_」(アンダーバー)で区切った命名となります。
・アクションファイル: (アクションディレクトリ)/example1/Index.php ・アクションクラス名 Example1_Index
ただし、ディレクトリやファイル名の先頭に「_」をつけた場合、外部からアクセスできないプライベートファイルになります。 (ファイル名の大文字/小文字を区別するOSでは)アクションディレクトリとアクションファイルの先頭が小文字の場合も外部からアクセスできません。 (routers.xml の設定からはルーティング可能です)
アクションで実行されるメソッド
次に、アクションファイルが読み込まれたあと、どのメソッドが起動されるかについて説明します。
起動するメソッドについては、リクエストされた(デフォルトでは)アクションパラメータにより異なりますので、 アクションパラメータについて先に説明します。
アクションパラメータは、URL上に特定のパラメータを付加することにより、 アクションファイルを特定した後、どのメソッドを起動するか判定するパラメータとなり、2つのパターンがあります。
1つめは、URLに組み込むパターンです。
アクションパラメータは、例えば下記のようなURLとなれば、「sample」(ファイル名の拡張子判定以外の「.」より前)部分になります。
URL:
/example.php/example1/sample.index.html
もう1つめは、URLパラメータに設定するパターンです。
コントローラ起動パラメータに設定したパラメータ名をリクエストされた場合にアクションパラメータとすることができます。
---------- 起動パラメータ ---------- … $config = array( 'type' => '', 'project_dir' => '', 'app_name' => 'example', 'action_key' => 'action' ); // コントローラ起動 $controller =& SyL_Controller::getController($config); $controller->stream(); … ---------- URL ---------- /example.php/example1/index.html?action=sample
このアクションパラメータを踏まえ、アクションファイル内のどのメソッドが起動されるかは、 先ほどのアクションマッピングの設定に起動するメソッドを追加した設定が下記になります。
…
<action path="(.+)\.php"
method="execute{action}">
</action>
…
method : 起動するメソッド
※{action}はアクションパラメータに変換される。
methodで定義されている「execute{action}」メソッドが起動するのですが、
{action}は先ほどのアクションパラメータ(先頭大文字)に変換されてから実行されます。
例えば、アクションパラメータが「sample」なら「executeSample」メソッドが実行されます。
(アクションパラメータが無い場合は、「execute」メソッドが実行されます。)
アクションの親クラス
全てのアクションクラスは、SyLAction クラスを継承します。アプリケーション作成初期は、
(SYL_APP_DIR) /lib/App/AppAction.php
にアプリケーション共通の親クラスがあり、個別のアプリケーションクラスは、このクラスを継承します。
要するに、
SyLAction > AppAction > (個別アプリケーションクラス)
になります。
AppAction クラスには、アクション前/後に実行するメソッドが定義されています。 それを編集することにより、アクションの前/後に実行する共通処理を定義できます。 また、アクション共通メソッドの追加も可能なので、別々のアクションで使用される共通メソッドをまとめられます。
class AppAction extends SyL_Action { // アクションメソッド実行前に実行されるメソッド function preExecute(&$data, &$context) { } // アクションメソッド実行後に実行されるメソッド function postExecute(&$data, &$context) { } }
「4.1 アクションの動作仕様 」で説明しましたが、
[URL] /example.php/example1/sample.index.html [アクションファイル] {SYL_APP_DIR}/actions/example1/Index.php [クラス] Example1_Index [メソッド] function executeSample(&$data, &$context)
例えば、URL「/example.php/example1/index.html」にアクセスした場合、 アクションファイル「{SYL_APP_DIR}/actions/example1/Index.php」が読み込まれ、 クラス「Example1_Index」のメソッド「executeSample」が実行されるので、 単純にURL「/example.php/example1/index.html」に対応するアクションを作成する場合、 テキストエディタ等で、クラス「Example1_Index」とメソッド「executeSample」を記述した アクションファイル「{SYL_APP_DIR}/actions/example1/Index.php」を作成します。 (※文字コードは、「EUC-JP」推奨)
{SYL_APP_DIR}/actions/example1/Index.php <?php class Example1_Index extends AppAction { function Example1_Index() { } function executeSample(&$data, &$context) { } } ?>
外部からGETまたはPOSTパラメータを取得する場合は、$dataオブジェクトのgetメソッドで取得します。 パラメータの取得は、同名のパラメータが無い限り、GET、POSTを意識することなく取得できます。 存在しないパラメータ名が指定された場合は、nullを返します。
例)GET /hoge.php/example1/index.html?sample=get_parameter … function execute(&$data, &$context) { $sample = $data->get('sample'); echo $sample; // get_parameter } …
ビュー(テンプレート)には、データオブジェクト($data)がそのまま渡されますので、
アクションからビュー(テンプレート)にパラメータを渡す場合は、データオブジェクトに変数をセットします。
なお、変数名の先頭に「_」が付加された変数は、セットできません。
例)アクション … function execute(&$data, &$context) { $data->set('sample', 'test'); //「sample」変数に「test」値をセット $obj = new stdClass(); $data->setRef('obj', $obj); // 参照でセット } … 例)テンプレート(デフォルトビュー) … <?php echo $sample; ?> …
セッションに値をセットしたり、値を取得するには、$contextオブジェクトから取得したリクエストオブジェクトの各setSession、getSessionメソッドを使用します。
… function execute(&$data, &$context) { $request =& $context->getRequest(); $request->setSession('sample', 'session_parameter'); echo $request->getSession('sample'); // session_parameter } …
セッションを破棄する場合は、セッションオブジェクトを取得して、delete、deletesメソッドを使用します。
… function execute(&$data, &$context) { $request =& $context->getRequest(); $session =& $request->getSessionObject(); $session->delete('sample'); // sampleセッション変数を削除 $session->deletes(); // 全セッション変数が破棄されます。 } …
また、セッションは設定ファイル(defines.xml)の定数SYL_SESSION_*により セッション名やセッション有効パスの変更などが可能です。
※セッションに関する情報は、「6.1 セッション」も参照してださい。
クッキーに値をセットしたり値を取得するのも、$contextオブジェクトから取得した$requestオブジェクトを使用します。 クッキーをセットするにはsetCookieメソッド、クッキーから値を取得するには、getCookieメソッドを使用します。
… function execute(&$data, &$context) { $request =& $context->getRequest(); $request->setCookie('sample', 'session_parameter'); echo $request->getCookie('sample'); // session_parameter } …
クッキーを破棄する場合は、クッキーオブジェクトを取得して、delete、deletesメソッドを使用します。
… function execute(&$data, &$context) { $request =& $context->getRequest(); $cookie =& $request->getCookieObject(); $cookie->delete('sample'); // sampleクッキー変数を削除 $cookie->deletes(); // 全クッキー変数が破棄されます。 } …
また、クッキーは設定ファイル(defines.xml)の定数SYL_COOKIE_*により挙動が変わります。
※クッキーに関する情報は、「6.2 クッキー」も参照してださい。
ファイルアップロードも同様に$contextオブジェクトからファイルアップロードオブジェクトを取得して操作を行います。
下記のようにファイルアップロードフォームを作成した場合、
… <form name="form1" action="..." method="post" enctype="multipart/form-data"> <input type="file" name="fname" size="30"> <input type="submit" value="OK"> </form> …
サーバー側(SyLフレームワーク側)では、$contextオブジェクトからファイルアップロードオブジェクトを取得して、 getメソッドでファイルアップロード情報を取得できます。(ほぼ$_FILESと同じ内容です)
… function execute(&$data, &$context) { $request =& $context->getRequest(); $file =& $request->getFileObject(); // アップロード処理エラー判定 if ($file->isError()) { // エラー // $error = $file->getErrorMessage('fname'); } // アップロードした一時ファイル情報を取得 $fileinfo = $file->get('fname'); //print_r($fileinfo); } …
アップロードしたファイルは、最初一時ディレクトリにありますが、何もしなければスクリプト終了時に消えてしまいます。 ファイルの内容を一時的に参照するのであれば、一時ファイル参照情報を元にファイル処理を行えばいいのですが、 サーバー側にファイルを残す必要性がある場合は、別ディレクトリに移動しておかなければなりません。
ファイルを特定のディレクトリに移動するにはuploadメソッドを使用します。
uploadメソッドは、アップロードしたファイル名で、SYL_UPLOAD_DIR定数で指定されたディレクトリ(デフォルト)に保存されます。 SYL_UPLOAD_DIR定数で指定されたディレクトリ以外に保存したい場合は、setUploadDirメソッドで保存ディレクトリを指定します。
… function execute(&$data, &$context) { $request =& $context->getRequest(); $file =& $request->getFileObject(); // 保存ディレクトリの変更 // $file->setUploadDir('/path/to/savedir', true); // アップロード処理(一時ディレクトリからの移動) $file->upload('fname'); // アップロード処理エラー判定 if ($file->isError()) { // エラー // $error = $file->getErrorMessage('fname'); } } …
※ファイルアップロードに関する情報は、「6.3 ファイルアップロード」も参照してださい。