AwesomeFrameworkにForwardを実装しました。

AwesomeFramework-0.2.zip

<?php
include $_GET["action"] ? $_GET["action"].".php" : "default.php";
function forward($action) { include $action.".php"; }
?>

なんて高機能なんだ。
これでViewにforwardすることでModelとViewとControllerがそろってると言えるのではないだろうか!!

AwesomeTemplateEngineと同様、PHPファイル自体をテンプレートとして使用しますがAwesomeFrameworkはあくまで、$GLOBALS経由でテンプレートに値を渡します!

Actionのファイル:

<?php
$GLOBALS["message"] = "World";
forward("view");
?>

Viewのファイル:

Hello <?=$GLOBALS["message"]?>!

あと、今思いついたんですが、

module/
 action.php
index.php
index.php?action=module/action

ってやってモジュールによって管理する機能搭載!とか言えないでしょうか・・・。

Harukiからの平面波

個別処理に関数やクラスを使っても良いが、各caseで関数などのコールが入るだけで、やることは変わらない。

PHPのフレームワークは、個別処理をどう別けて記述するかを決めるところが肝であって、mojaviとか見たいに、コントローラクラスなんて作らなくてもいいやんと言う気もする。柔軟性高いし速いし。

Harukiさんのフレームワークについての考察。
振り分け処理(あえてコントローラーとは言わない)の最小限サンプルを書かれています。

確かにFront Controller Patternといってもやりたいことはこれだけスね。
それに比べた場合、他のフレームワークの便利な点は何か?

  • 名前空間が分かれている
  • エントリポイントに制約(仕様)がある

名前付けとか開放・閉鎖原則とか単にオブジェクト指向の便利な点と変わらなくなってしまいました。

クラスになると名前空間を分けることができるけれど、(クラスに対してコンパイラがやっているように)関数名と変数名にPrefixを付ければ同じことになる。

JavaやPHP5のように仕様を強制できる仕組み(インターフェースとか)があると個別処理が交換可能なことが保障されるので便利。だけど仕様を覚えるのが面倒。

これを全部とっぱらって柔軟性が高くて習得コストが低いのを売りにしたフレームワーク(的なもの)っていう方向性も面白いなと思いました。

そこで、昔面白いなと思った「7行のテンプレートエンジンAwesomeTemplateEngine」に対抗して「1行のフレームワークAwesomeFramework」を作ってみました。

AwesomeFramework 0.1(HelloWorldサンプル付属)

そのソース:

<?php include $_GET["action"] ? $_GET["action"].".php" : "default.php"; ?>

これを使ってある程度のアプリを作ろうとすると、逆に名前空間のありがたさとか(グローバル変数地獄)を身をもってわかって良いかも知れない!

Mojavi2、こんなFilterはどうだろうか。

<?php
class MessageFilter extends Filter {
    function execute(&$filterChain, &$controller, &$request, &$user) {
        if ($request->hasAttribute("messages") === false) {
            // global messages
            $globalMessagesPath = BASE_DIR."configs/messages_".DEFAULT_LANG.".ini";
            if (is_readable($globalMessagesPath)) {
                $messages = parse_ini_file($globalMessagesPath);
            }
        }
            // module messages
            $messagesPath = $controller->getModuleDir()."config/messages_".DEFAULT_LANG.".ini";
            if (is_readable($messagesPath)) {
                $messages = array_merge($messages, array($controller->getCurrentModule() => parse_ini_file($messagesPath)));
            }

            $filterChain->execute($controller, $request, $user);
        }
    }
}
?>

messages_ja.ini, messages_en.iniとか置いといて読み込むことで多言語化の枠組みを提供するFilter。

アプリ共通のiniとモジュール毎のiniを両方読み込む。
strutsのように環境変数から勝手に切り替えるようにしたいんだけどHTTP_ACCEPT_LANGUAGEのパースが面倒臭い。MojaviのRequestにもServletRequest.getLocale()があれば・・・。

先週、社内でPHPに関する質問メールを頂きました。

「MojaviのRequestクラスのsetAttributeメソッドとsetAttributeByRefメソッドの違いがわからない。」

というものです。
値渡し参照渡しの違いですが、おれ自身、参照を本当に理解しているかあやしいもんです。本当に理解していないとわかりやすく説明することはできません。
概念を本当に理解したかどうかは言語化(コード化)、もしくは図にできるかどうかで判断することにしています。

Prove it.(証明せよ)」ということでMojaviでのサンプルを作ってみました。

ref-0.1.zip

<?php
class DefaultIndexAction extends Action {
    function execute(&$controller, &$request, &$user) {
        $value = "foo";

        $request->setAttribute("value", $value);        // real
//        $request->setAttributeByRef("value", $value);    // ref

        $value = "bar";

        echo $request->getAttribute("value");
        return VIEW_NONE;
    }
}
?>

setAttributeとsetAttributeByRefで動作が変わる最小限サンプルです。
質問への回答はメールに返信してこのサンプルも一緒に送ったんですが、果たして解りやすい説明だったかどうか・・・自信がイマイチです。

[を] PHP をいじってみた

PHP、すごく手軽で良いですね。セッション管理が楽だー。
これならさくさくといろいろ面白いサービスが作れそうですね。
とりあえず、今後はDBとの連携を一通りやってみるつもり。

いつも楽しみに見ているたつをのChangeLogのたつをさんがPHPをはじめられたっ!

せっかくなので自分が「そういうの最初から教えておいてくれよ」と思ったことを書き出してみます。

PHP Switcher Q&A

Q. GETやPOSTを手っ取り早く取りたいんだけどCGIモジュール的なものは?

A. PHPコアの機能に含まれています。GETやPOSTのデータは自動的にグローバル変数の$_GET, $_POSTに連想配列として入っています。

Q. セッションは?

A. PHPコアの機能に含まれています。$_SESSIONというグローバル変数(連想配列)に代入するだけでセッションにデータが入ります。

Q. 配列と連想配列はどう違う?

A. 配列と連想配列は内部的には同じモノです。添字に文字列を指定すると連想配列になります。(添字に数字と認識できる文字列を入れると自動的に数値に変換されます。)

Q. ヘッダはどうやって書く?

A. Apacheモジュール版PHP(mod_php4)ではヘッダは自動的に付与されます。明示的に書きたい場合はheader関数を使います。それに対してコマンドライン版PHP(cli)が存在します。

Q. サードパーティ製モジュールは?

A. PerlでいうCPANにあたるPEARというリポジトリサイトがあります。(モジュールの登録には他のPEARメンテナの賛成投票が5票以上必要でstable/unstableという分類もあるため、CPANよりモジュール数が少ない代わりに一定の品質は保障されています。)

Q. PHP自体に機能を追加したい

A. Pure PHPのみのPEARに対して、Cで書かれたPHP extentionのリポジトリサイトとしてPECL(ぴくる)があります。

Q. Template-toolkit的なものは?

A. Smarty Template Engine。

Q. PHP自体がHTMLに埋め込めるんだからテンプレートエンジンなんていらないんじゃないの?

A. そういう考えのもと、PHP自体をテンプレートとして扱うSavantというテンプレートエンジンもあります。

Q. Webアプリケーションフレームワークは?

A. Mojavi
その他、国産フレームワークのMapleEthna、Java Seasar2のPHPポーティングS2PHP5などが有名です。

Q. O/Rマッパーは?

A. PEAR DB_DataObject。PHP5ではPropelなど。

PHP全体の印象としては、便利なものは少々言語デザイン的に美しくなくても標準関数にしちゃえ的節操のなさが良いところでもあり悪いところでもある。といったところでしょうか。

これを期に他言語をメインにしている人もちょっとPHPを触ってみる、もしくは多言語のライブラリやツールをPHPに移植してみるというのはどうでしょうか。

php_study.jpg

第一回PHP勉強会 in Tokyo行って来ました。
PHPの濃い話がたくさん聞けてとってもためになりました!

内容はたくさんあって書ききれないですが、ためになったことメモ。(順不同)

  • DI/AOP
  • 配列と連想配列は同じ
  • 配列の添え字はintかchar*、値はzval
  • Maple, Dicon
  • Ethna info(早速パクッてMojavi info作りたい)
  • CatalystはRails似
  • Apache + FastCGI不安定
  • session_id()でホストアドレスとかくっつければ複数Webサーバセッション保存でもセッションIDかぶらない
  • PHP4限定、$this経由Factoryクラス(factoryメソッドじゃなくて)
  • QFのPasswordエレメント、Hiddenアスタリスク問題対応策
  • 外人はConfirm(確認画面)作らない
  • 日本では一時期の法律問題でConfirm作る文化がある可能性(Historical reason pattern)
  • SimpleXMLはアクセスしたときオブジェクトができる
  • SimpleXMLではあらかじめネームスペースを指定してから取る(=非実用的)
  • Railsでmixin前提設計
  • PEAR XML_Serializer不可逆シリアライズ
  • GooはPHPベースが多い
  • Popoon = PHP版Apache Cocoon
  • Maple, Dicon, QF, DBDO, FormBuilder
  • DreamWeaverDWTSmartyDWTプラグイン

おれの方ではMojaviでのパターンについて話させていただきました。

MSICC.pdf
msicc-1.4.zip

ある程度の規模で開発標準を決める場合、利便性よりも「共通の決まりを使用すること」や「繰り返し使うこと」の方が重要になってきてしまいます。
Mojaviでの開発標準やコーディング規約関連が落ち着いたらRailsやSeesaa、MapleやEthnaなど試したいです。

フォワードは

$controller->forward("modName", "actName");

で、いけるのにリダイレクトは面倒。
勝手な拡張は厭なので、ヘルパクラスを作ってみました。

<?php
class URIUtil {
    function redirect($modName, $actName, $opt = null) {
        $params = array(MODULE_ACCESSOR => $modName, ACTION_ACCESSOR => $actName);
        if (is_array($opt)) $params = array_merge($params, $opt);
        Controller::redirect(Controller::genURL($params));
    }
}
?>

使うほうはこんな感じで

URIUtil::redirect("modName", "actName");

URL_FORMATに依存しなくて気持ちいい!

PEAR好き野郎としてはMojaviのAPIリファレンスもPEARデザインで見たい。

作りました。

Mojavi 2.0.0 API Reference Manual

やば、見やす!

[結] 2005年6月 – 結城浩の日記

RSSフィードでさくさく文章を読んでいると、 ときどき「タイトルしかないサイト」がある。 そういうサイトはだんだん読まなくなっていく傾向にある。 逆に、RSSフィードで読んでいて(つまりそのサイトのデザインとは無関係にコンテンツだけ読んでいて)「面白いなあ」と感じるサイトは、 よく記憶しているように思う。 というわけで、みなさんRSSフィードにたくさん文章を入れましょう。

RSSでDescriptonが短かったりすると段々読まなくなっていくという話。

このサイトのもちょびっとしかDescriptionが無いことに気づいたので最新のMTのテンプレをもらって入れ替えました。

というか、Planet PHP Japanで全文出ないと悲しいからです!

Mojaviのロギングやエラーハンドリングを見ていて、普通のPHPでもエラーハンドリングについてよく解ってなかったことに気づきました。

PHP自体の機能を使ってシンプルなエラー処理の正解(宣言してしまえば反対意見が出るまで正解と言い張れる)を作ってみました。

seh-1.0.zip

<?php
include_once("getContents.php");

// 行数の取得
function getNumLines() {
    $contents = getContents();
    if ($contents === false) {
        trigger_error("getNumLines(): 行数の取得に失敗しました", E_USER_WARNING);
        return false;
    }
    return count($contents);
}
?>

seh.png

  • エラーメッセージはその関数(メソッド)を実行した奴から見た内容にする。
  • pg_connectの失敗だってE_WARNINGなのでJavaの(Exceptionじゃなく)Errorのようにスクリプトを実行し続けることができないような致命的なものだけE_USER_ERRORレベルのエラーを発生させる。(大体はE_USER_WARNING)
  • どのレベルからエラーを出すかは、error_reportingディレクティブで設定する。
  • ログはerror_logディレクティブで設定する。

これであってるのかどうか気になる!
すごい基本なのにわからないこと多過ぎです。