>>前に戻る

FunctionExecution

1. ジョインポイント

関数定義

2. 対象AST要素

AOWP_PHPFunctionElement

3. ジョインポイントを選択するポイントカット

AOWP_FunctionExecutionPointcut

4. ポイントカットで指定できるパラメータ

関数名
引数の数

5. アドバイス本体内で使用できるコンテキスト情報

以下の表に記したコンテキスト情報がアドバイス本体内で使用できます。

表 アドバイス本体内で使用できるコンテキスト情報

仮引数 戻り値
BeforeAdvice ×
AfterAdvice
AroundAdvice ×

仮引数の取得は func_get_args( ) によって行っています。全てのアドバイス本体内で、
   $args0 = $context->args[0];
のように、配列として仮引数の値は使用できます。

Afterアドバイスは関数終了後に実行されるので、その関数の戻り値をアドバイス本体内で、
   $retVal = $context->returnValue;
として、使用することができます。Beforeアドバイスは、関数実行前に実行されるので、戻り値は利用できません。Aroundアドバイスは、関数定義そのものを置換するので、戻り値は利用できません。ただし、アドバイス本体内で proceed を実行した場合の戻り値は利用できます。

アスペクトの記述例

  1. class TestFunctionExecutionAspect extends AOWP_Aspect {
  2. public function __construct ()
  3. {
  4. // アドバイスの種類を指定
  5. $advice = new AOWP_BeforeAdvice();
  6. // 実行するアドバイス本体を指定
  7. $advice->setAdviceBody('func');
  8. // 関数名はfunc、引数の数は任意の、関数定義を選択
  9. $advice->setPointcut( new AOWP_FunctionExecutionPointcut('func',-1) );
  10. // 上記で指定したアドバイスをアスペクトに登録
  11. $this->addAdvice($advice);
  12. }
  13. public function func($context)
  14. {
  15. echo '*** func before execution ***<br/>';
  16. echo '*** func before execution I got a args0 = '.$context->args[0].'***<br/>';
  17. echo '*** func before execution I got a args1 = '.$context->args[1].'***<br/>';
  18. echo '*** func before execution I got a args2 = '.$context->args[2].'***<br/>';
  19. }
  20. }

6. 複数のアドバイスが当ジョインポイントに織り込まれる場合の挙動

(1)同じ種類のアドバイス
1.Before1 → Before2 または After1 → After2
Beforeアドバイスを X, Y とすると、
   X → Y
の順番でアドバイスを登録した場合、
   X → Y
の順番でアドバイスは実行されます。これは Afterアドバイスでも同じです。


2.Around1 → Around2
Aroundアドバイスを、X,Y とすると、
   X → Y
の順番でアドバイスを登録した場合、実行されるのは Y だけとなります。これは、アドバイスXによって、関数本体定義が置換された後、さらにそれをアドバイスYによって置換するためです。
Y本体内でproceedを実行した場合、Xが実行されます。このとき、X本体内で proceed を実行した場合、元(original)関数が実行されます。


(2)異なる種類のアドバイス
1.Before1 → After1, または After1 → Before1
BeforeアドバイスをX, Afterアドバイスを Y とすると、
X, Y のアドバイスの登録の順番に関係なく、
   X → Y
の順番で実行されます。


2.Around1 → Before1
AroundアドバイスをX, BeforeアドバイスをYとすると、
   X → Y
の順番でアドバイスを登録した場合、
   Y → X
の順番で実行されます。これは、アドバイスXによって、関数本体定義が置き換えられて出来た新しい関数定義に対し、アドバイスYが織り込まれるからです。


2-2. Before1 → Around1
上記の逆で、AroundアドバイスをX, BeforeアドバイスをYとすると、
   Y → X
の順番でアドバイスを登録した場合、実行されるのは X だけです。これは、アドバイスYが織り込まれた関数定義全体を、アドバイスXが置換するからです。


3.Around1 → After1
AroundアドバイスをX, AfterアドバイスをYとすると、
   X → Y
の順番でアドバイスを登録した場合、
   X → Y
の順番で実行されます。


3-2.After1 → Around1
上記逆で、AroundアドバイスをX, AfterアドバイスをYとすると、
   Y → X
の順番でアドバイスを登録した場合、実行されるのは X だけです。

7. 例外の扱い

afterアドバイスの実行以前に例外がスローされた場合、afterアドバイスは実行されません。