2011-06-22 7 views
4

特定のメソッドの前後で実行する必要のあるロジックを持つベースクラスを指定すると、異なる派生クラスで大きく異なるパラメータが使用されます。PHPでのフックメソッドの実行

abstract class Base{  
    public function pre(){ print "Runing Base::pre()\n"; } 
    public function pos(){ print "Runing Base::post()\n"; } 
    abstract public function doIt(); 
} 

class Cheating extends Base 
{ 
    public function doIt(){ 
     $this->pre(); 
     print "Doing it the cheating way\n"; 
     $this->pos(); 
    } 
} 

しかし、私は実際にやってみたいのラインに沿っている:

class Alpha extends Base 
{ 
    public function doIt($x, $y){ 
     print "Doing it in Alpha with x=$x, y=$y"; 
    } 
} 

class Beta extends Base 
{ 
    public function doIt($z){ 
     print "Doing it in Alpha with z=$z"; 
    } 
} 

、常に前とPOSメソッドを実行するためのいくつかの方法を持っている、しなくても、一例として、 doItメソッド自体を変更してください。

明白な方法、のdoItは、ベースのすべての派生全体で均質でなければならないようなものになるだろう:

abstract class Base 
{ 
    public function pre(){ print "Runing Base::pre()\n"; } 
    public function pos(){ print "Runing Base::post()\n"; } 

    public function process($a,$b){ 
     $this->pre(); 
     $this->doIt($a,$b); 
     $this->pos(); 
    } 

    abstract public function doIt(); 
} 

class Wishful extends Base 
{ 
    public function doIt($a, $b){ 
     print "Doing it the Wishful way with a=$a, b=$b\n"; 
    } 
} 

問題、我々はのdoItの各実装上のパラメータの異なる数と種類を持っているので、それはそれは、そこにあります実際に問題を解決するものではありません。

「フック」の場合と同じように聞こえますが、どのようにそれらを実装するのでしょうか?または、問題を解決するための他のまともな方法...私はちょうど欠けている簡単な方法があるはずだと思う - おそらく間違ったものを円で考える。

ありがとうございます! http://php.net/manual/en/function.call-user-func-array.php:で行うことができ、可変引数を指定して呼び出す

function process() 
{ 
    $this->pre(); 
    $result = call_user_func_array(array($this, 'doIt'), func_get_args()); 
    $this->post(); 
    return $result; 
} 
+0

あなたの方法はプライベート作ると – datasage

答えて

0

+0

かなり、それは私にちょっと面倒ですが、まあ... PHPは私の繊細な美学を満たすために存在しません:)ありがとう、それはそれを解決します。 – Wagemage

+0

:)私はそれが本当に醜いと言っています。> Pythonで書かれたラッパーメソッドと比較してください。 –

0

は、それはあなたのような何かをしたいように聞こえます。 $ thisをオブジェクトとして渡します。引数をフェッチ

は少しトリッキーですが、__callで行うことができます:あなたはaspect-oriented programmingをご覧くださいhttp://www.php.net/manual/en/language.oop5.overloading.php#language.oop5.overloading.methods

+0

がそのように聞こえ__call魔法のメソッドを使用してそれらを実行します。

はまた、ここでは関係SO質問です。ちょっと地味だけど...ねえ、もしそれがあれば、それはやる - ありがとう! – Wagemage

2

lithium framework's filterシステムはそのようなものを使います。 Zend Framework 2もAOPを使用する予定です。

エンジンレベルで関数呼び出しをインターセプトする場合は、PECLのinterceptを使用できます。

Googleはまた、nice frameworkから多くを学ぶことができます。そのコードを見てください。 https://stackoverflow.com/questions/4738282/are-there-any-working-aspect-oriented-php-libraries

+0

クール。私は見てみましょう。 Ars longa、vita brevis ...と締め切り日ですが、おそらくそれはそれに値するでしょう。ありがとう:) – Wagemage