AOPが実装されれば

・・・以下のようなInterceptorが「components/」ディレクトリ以下のクラスにかけれるようになります。

class TraceInterceptor {
  function invoke(&$invocation) {
     // Interceptしたインスタンスを取得
     $instance =& $invocation->getInstance();
     $className = get_class($instance);

     // Interceptしたメソッド名を取得
     $methodName = $invocation->getMethodName();

     // Interceptしたメソッドの引数を取得(この例では出番はないですが・・・)
     $arguments =& $invocation->getArguments();

     // 前処理(Before Advice)
     $log =& LogFactory::getLog();
     $log->trace("${className}#${methodName}の前処理が実行されました", "${className}#${methodName}");

     $result = $invocation->proceed();

     // 後処理(After Advice)
     $log->trace("${className}#${methodName}の後処理が実行されました", "${className}#${methodName}");     
  }
}

「$invocation->proceed()」でInterceptした元の関数が実行されるので、その前後でしたい処理をするという感じですね。(MapleのFilterChainの仕組みをご存知の方はほぼ同じだと思っていただけるかと)

ぱっとみて気が付いた方はいらっしゃると思いますが、Seasar2AOPそのままです。なんとかそれを実現しようと思ってます。

組み立て具合もSeasar2と同じように以下のようになります。

  • まず、InterceptorクラスのインスタンスDIContainerに登録(dicon.iniに記述というとですね)
  • 登録したコンポーネント(Intercepter)を特定のクラスのメソッドに関連付ける(これもdicon.iniで行う。最終的にはHawkさんのDI2を拡張して「apect://」みたいな指定になるといいですね。)
  • 関連付けされた特定のクラスのメソッドが実行されるとInterceptorが発動する

Seasar2は本当に参考になります。DI+AOPという組み合わせであれば、PHP4でもなんとかなりそうです。というか、DI+AOPという組み合わせでないと使い物にならないと思います。

Seasar2はやりたいことを最短距離でやるという思想を感じるので、ほんとうにしっくりきます。おそらく他のフレームワークとかももともとはそうだったんだろうけど、いろいろ機能追加を続けた結果、もともとは何をめざしていたの?と思うようなものが多いので。

Mapleはやりたいことを最短距離で行うフレームワークでありたいと思います。