Yapafi - Yet Another PHP Application Framework Interface

Tutorial

ディレクトリ構成

yapafi.php
フレームワーク本体です。ディスパッチャもかねています
.htaccess
mod_rewriteのルール等が設定されています。
yapafi.ini
Yapafiを動かす上で必要な設定値を記述します。拡張子はiniですが、記述ルールはphpと同じです。
app.ini
アプリケーション固有の設定(DB接続情報等)を記述します。こちらも同様に記述ルールはPHPと同じです。
extlib/
便利ライブラリが格納されています。PEARライブラリ等を必要に応じて配置します。
app/
ここにコントローラを配置します。
view/
ここにビューを配置します。
model/
ここにモデルを配置します。
work/
ここはログやセッション情報が格納されます。

インストール

ダウンロードしてきたファイルのhtdocs以下一式をアプリケーション配置ディレクトリにコピーしてください。

.htaccessの設定

以下の行をアプリケーションの設置パスに応じて書き換えてください。
(Apache + mod_rewrite前提になっています。)

RewriteBase /~yapafi/

これでアプリケーションにアクセスして画面が表示されれば設置は完了です。

実装における前提知識

コードはコントローラ、テンプレート含めて全てUTF-8(BOM無し)で記述してください。これは出力文字コードがShift_JISであっても同様です。

テンプレートファイル以外には、PHPコードの終端を表す"?>"を記述してはいけません。これは、余計な空白がバッファに送られるのを防ぐためです。


全体の流れ

全体流れ

コントローラの設置

URLとコントローラのマッピング

URLとコントローラ名はマッピングされており、自動でコントローラが呼び出されます。例えば、

[アプリケーション配置パス]/example

にアクセスがあった場合、app/example.phpがコントローラとして呼び出されます。

上記のように"app/"以下に拡張子phpでコントローラを配置します。また、index.phpは特殊なコントローラで、アプリケーションのルートにアクセスした場合にも呼び出されます。

命名規則

コントローラファイル名には、

のみを使用可能です。またファイル名の先頭やアンダースコアの直後は半角小文字アルファベットしか使用できません。また、末尾をアンダースコアにすることは出来ません。

OKな例

hoge.php
fuga2.php
sample_fuga.php
hoge/fuga_piyo.php  # ディレクトリによる階層分けも可能です

NGな例

_hoge.php           # アンダーバーが先頭にある
2hoge.php           # 数字で始まっている
fuga_2dd.php        # アンダーバーの直後に数字がある
sample_fuga_.php    # アンダーバーで終わっている
hoge/_fuga_piyo.php # ディレクトリ区切りの直後にアンダーバーがある
hOg+e.php           # 使えない記号や大文字が入っている

ファイル名とコントローラークラスのマッピング

コントローラの雛形は以下のような感じです。

example.php

<?php
// Yapafi_Controllerを必ず継承します(本来は直接継承ではなく孫クラスを推奨)
class Example_c extends Yapafi_Controller {
    function runGet() {
        // ここにGETメソッドの時の処理を記述します。

        // stashメンバ変数にテンプレートに差し込む文字列をセットします
        $this->stash = array( 'title' => 'example'); //テンプレートの$title変数に文字列'example'をセット

        // メソッドを抜けた後自動的にテンプレートが呼び出されます。
    }

    function runPost() {
        // ここにPOSTメソッドの時の処理を記述します。
        redirect('example'); //POST時はビューを表示せずリダイレクト推奨。
    }
}
// ?>を記述してはいけません。

ファイル名に応じてクラス名が決定されます。ファイル名をPascalCase(UpperCamelCase)に置き換え、末尾に'_c'を付与したものがクラス名になります。また、ディレクトリ区切りはアンダーバーに置き換えます。

example.php            → Example_c
example_abc.php        → ExampleAbc_c
fruit_apple/orange.php → FruitApple_Orange_c

コントローラでの処理終了後、テンプレートが自動で呼び出されます。テンプレートファイル名を明示的に指定したい場合は、run*メソッド内でsetViewメソッドを呼び出して以下のように記述してください。

    function runGet() {
        // ここにGETメソッドの時の処理を記述します。

        $this->setView( 
            'something.tpl', // 第一引数にテンプレートファイルを指定します。
            // 第二引数に配列で差込文字列を指定します
            // ($this->stashを既にセット済みの場合は省略可能です)
            array(           
                'title' => 'example', //テンプレートの$title変数に文字列'example'をセット
            )
        );
    }

ちなみにあまり推奨しませんが、runGet(), runPost()メソッドを定義しないで、run()メソッドを定義することでGETとPOSTのロジックを共通化できます。

モデル

モデルクラスは特に準備していません。適宜モデルを準備してください。

モデルクラスがないからと言って、コントローラに処理を書きすぎないように注意してください。コントローラ内でデータ参照・更新処理はしないようにしましょう。

逆にモデルは環境依存のない状態で実行できるように記述すべきで、コントローラはその受け渡しのために存在します。モデル内で環境変数やリクエスト変数の参照はしないようにしましょう。

例えばモデルをCLI(バッチ)から呼び出したとしても同様の結果セットが返り、更新処理が走るように記述すべきです。

モデルはテストコードを準備し、単体で機能のテストが出来るようにしましょう。

テンプレート

テンプレートは"view/"以下に拡張子.tplで配置します。拡張子は.tplですが記述ルールは生PHPと同じです。

コントローラ内で明示的にテンプレートファイルを指定しなかった場合、コントローラと同じファイル名のテンプレートファイルが呼び出されます。

コントローラ内でテンプレートに受け渡された連想配列は、キーが展開されて変数として使われます。

<html>
<body>
<?= $title ?><!-- ←ここにtitleの中身が入ります。 -->
</body>
</html>

自動エスケープ

セキュリティを鑑みて、テンプレートへの差込文字列は自動でHTMLエスケープされます。多重配列になっている場合でも再帰的にエスケープされます。

但し、多重配列のキーはエスケープされません。また、イテレータオブジェクト等を保持して値を格納している場合もエスケープ対象外です。

逆に自動エスケープの対象としたくない場合は、raw_str関数でラッピングすることによって、自動エスケープ対象外にすることが出来ます。ブログパーツ等、外部から取得したHTML等をそのまま差し込む場合に有効かと思いますが、何でもかんでもraw_strを使わないようにしてください。また、外部から取得したHTMLはそのまま信用しないようにしましょう。

$this->stash = array(
    'string'    => '<p>sample</p>', // エスケープされる → '&lt;p$gt;sample&lt;/p$gt;'
    'hash'      => array( // 連想配列の中身もエスケープされますがキーはエスケープされません。
        'marks' => '<<<><<""<<>',
        'test' => 'aaa',
    ),
    'object'    => $some_iterator, // オブジェクトの中身はエスケープされません
    'raw_html'      => raw_str('<p>ここはエスケープされません</p>'), // raw_str関数でラッピング
);

$_SESSION, $_GET, $_POSTの中身は当然自動エスケープされませんが、テンプレートでこれらの値を直接セットするのはやめましょう。

さらに詳しく知りたい場合

解説一覧コントローラーの動きについてをご覧下さい。