404 motivation not found | t_ishidaのブログ

4月/08

14

フレームワーク(笑)の使い方

能書き

フレームワーク(笑)とは?

t_ishidaが、PHPの勉強のために作ってみたフレームワーク的なもの。

フレームワークは薄く、ライブラリは豊富に、と言う、t_ishidaの自己満足が詰まったものPHPのジャンクなコード群です。

考え方

MVC(笑)です。

なんか、そんな格好良いものじゃなくて、テストのしやすさを追求しているうちにこうなった。みたいな感じです。現状では理想系には程遠い状況です。ただ、自分では使い始めちゃってるのと、リアルで知っている人に聞かれたらイチイチ聞かれるのも面倒なので、ここにまとめておきます。なお、勝手に使ってOKですし、勝手にソースを直してもOKです。勝手にして下さい。が、何も保障しませんし、何も出来ません。あとlibに、simpletestとspycが入ってますが、これは僕が作った訳では有りません。依存クラスです。こいつらは多分、これの作者に著作権的なものがありますので、こいつらを弄ったり使ったりする時には、それに従ってください。

ダウンロード

プロフィールのところからダウンロードできます。多分。

使い方

index.php

全てのリクエストは、index.phpで受けます。URLは、”?action=[action]“って感じです。actionの名前に指定されたactionが呼び出されて処理する感じです。

  1. ブラウザからURLがコールされる。
  2. URLの中のactionで指定されたactionが動く
  3. actionが返したviewに渡されて、viewがperseされる
  4. ブラウザに行き着く

と言う感じです。

ディレクトリ構造

├─actions              ---Actionクラスを格納する
├─classes              ---エンティティとかを入れる
├─lib                  ---フレームワーク(笑)のコアが入っている
│  ├─drivers
│  │  └─db_catalog
│  ├─parsers
└─views                ---viewのPHPを格納する

作り方の手順を大雑把にまとめると、以下のようになります。

  • index.phpに、actions、viewsの定義を書く。実ファイルにコメントがあるんで、それを読んで上手く設定して下さい。
  • actionsにActionクラスを書きまくる
  • viewsにテンプレートを書きまくる
Actionクラス

libの下にある、ActionBaseを継承して作ります。

ちょうど、こんな感じになります。

<?php
require_once 'impressions.php';
require_once 'ActionBase.php';
class SaveComment extends ActionBase{
public function validate() {
$errors = array();
!$this->REQUEST['user_id'] && $errors[] = 'user_idが無いって(><)';
!$this->REQUEST['news_id'] && $errors[] = 'news_idが無いって(><)';
count( $errors ) && $this->Data['countents'] = join( "\n", $errors );
return ( count($errors) == 0 ) ;
}
public function doService(){
$imp = new impressions( );
$imp->search(
array(
'user_id' => $this->REQUEST['user_id'] ,
'news_id' => $this->REQUEST['news_id']      ,
)
);
$imp->user_id    = $this->REQUEST['user_id'];
$imp->news_id    = $this->REQUEST['news_id'];
$imp->comment    = $this->REQUEST['comment'];
$imp->will_write = $this->REQUEST['will_write'];
$imp->save();
$this->Data['result'] = 'OK';
return 'dummy';
}
}

主に実装するのはvalidate,doServiceの2メソッドです。他にも、doThisFirstとか、有れば適当なタイミングで実行するメソッドが有ります。無ければ実効しません。順番は、ActionBaseのrunメソッドを見てください。

  • validate = パラメータチェックですね。
  • doService = 実際のサービスを記入する場所ですね。

Actionクラスでは、$this->DataにActionの結果となるデータを格納します。

doServiceの戻り値に、viewsに定義してある、viewの名前を返します。

つまり、doService中に、正しく通ったら、正常なviewを返したり、例外的が発生したら、エラーページ的なviewを返したりなどしたりします。

Actionのコンストラクタに

$a = new Action(
[post] ,
[get]  ,
[session] ,
[cookie] ,
[file] ,
);

で渡され、

$this->POST;
$this->GET;
$this->SESSION;
$this->COOKIE;
$this->FILE;

として保存されます。

$this->REQUESTは、POSTとGETがマージされたものです。

これらの値を元に、actionして下さい。

あー、自動テストのコードとか貼り付ければわかりやすいかも。

やる気が出たらやるね。つまり、やる気が無いから、今は書かない。

テストの仕方としては、simpletestに一発食わせてやれば、好きなようにテストできます。ここは、スケルトン位はジェネレートするようにしたいが、出来ていない。

views
<html>
<body>
<ol>
<? foreach( $data['ranking'] as $rank ) : ?>
<li><a href="<?=$rank['url']?>"> <?=$rank['name']?></a></li>
<? endforeach; ?>
</body>
</html>

見たとおりです。ただのPHPです。

$dataと言う変数へActionクラスの$this->Dataで入れたデータがそのまんま入ってきます。PHPの本領である、高機能なテンプレートエンジンぷりを見せ付ける最大のチャンスとなるファイルです。

テストの仕方としては、頭に

<?php
$data = array(
'ranking' => array(
array( 'name' => 'hogehoge1' ,'url' => 'http://xxx.xxx.xxx/' ) ,
array( 'name' => 'hogehoge2' ,'url' => 'http://xxx.xxx.xxx/' ) ,
array( 'name' => 'hogehoge3' ,'url' => 'http://xxx.xxx.xxx/' ) ,
)
);
?>

とか作っておけばテンプレート自身を直接叩くと、正しくテンプレートが動いているかを確認できます。実際のテンプレートとして動かすときには$dataをコメントアウトしておけばOK。

なお、やりたくて現状できていない事の一つに、Controlerにデバッグモードを用意しておき、デバッグモード時には、POST,GET値のテストパターンを読み込んで、テンプレートから渡された、POST,GET値を自動比較するような機能を追加しておきたい。

ORマッパ(笑)

lib/EntityBaseを継承したものが、ORマッパ(笑)の概念です。

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

<?php
require_once 'define.php';
require_once 'EntityBase.php';
require_once 'drivers/DBDriver.php';
class tags extends EntityBase{
protected $TableName = 'tags';
public function __construct(  ){
parent::__construct( new DBDriver(DSN) );
}
}

以下の手順で自動ジェネレートできます。

  1. DBにテーブルを作って下さい
  2. create_entities.phpをコマンドラインから叩いて、質問に答えて下さい。
  3. classesに勝手にテーブル全部分のORマッパ(笑)が作成されます。

と言う内容です。今のところ、MySQLしか動きません。また、MySQLでも古いのだと動きません。

使うメソッド

  • search
    • $comment->search(1);
      • id1のデータで自身を満たします。
    • $comments = $comment->search( array( ‘news_id’ => 1, ‘user_id’ => 2 ) );
      • news_id = 1 and user_id = 2のデータで返ってきたものを自身の配列にして$commentsに返す
  • save
    • $comment->save();
      • idが一致するものが無かったら、insert、一致するものがあればupdateします。

なお、やる気のある人が居れば、ORマッパ(笑)は、DataDriverBaseを継承したものをコンストラクタの引数として受け取れます。DataDriverBaseのインターフェースさえ守っていれば、同じインターフェースのまま、データストアを自由自在に選択することが出来ます。

その他

ライブラリはまだ、そんなにありません。

適当にコード読んで下さい。

現状の開発状況

想定の40%位。

いろいろ

指針としては、この程度。他にも無駄に機能はあるけど、まあとりあえず。

既知のバグも沢山あるし、テスト不足も認識済み。

ワリとダサいプログラムだけど、それでも試したい人はお好きにどうぞ。

当面のTODO

  • テンプレートからのPOST,GETのテストモードを作る
  • ORマッパのカタログのキャッシュとか
  • Actionのスケルトンコードジェネレートとか
  • classesとActionのテストのスケルトンコードジェネレートとか
  • actionとviewについて、定義が無い場合にはディレクトリを検索して自動で呼び出すとか*1
  • 各種バグ対応
  • actionとかviewとか、いっぱいになる事が目に見えているので管理しやすい仕組みを考え直す。
  • 恐れ知らずに、ウケ狙いでSourceForgeに登録して、一人で笑ってみるとか

*1:一回作って消した。やっぱり必要だろ

Share and Enjoy:
  • Digg
  • del.icio.us
  • Google Bookmarks
  • Tumblr
  • email
  • Facebook
  • FriendFeed

RSS Feed

コメントはまだありません。

Leave a comment!

<< 落ち着くんだ、fizzbuzzを短く書いて落ち着くんだ。

複雑度ベースの見積もり方法 >>

Find it!

Theme Design by devolux.org

Tag Cloud