2012-03-11 9 views
1

私が探しているものが名前を持っているかどうかは分かりません。検索するのは少し難しかったので、私が尋ねていることが以前ここですでに答えられていれば謝ります。PHPでメソッドを呼び出すと、呼び出された後に自動的にコードが実行されます。可能?

私は抽象クラスを持っていますが、もちろんそれを拡張する他の多くのクラスがあります。

抽象クラスの抽象メソッドはrun()となり、すべての拡張クラスがこのメソッドを定義します。

私の問題は、run()メソッドが呼び出された後にいくつかの共通コードを呼び出すことですが、これを行うより良い方法があるかどうかを知りたいと思っています。

もちろん、それぞれの拡張クラスのすべての拡張クラスのrun()メソッドに私の共通コードを貼り付けることもできますが、それを行うと、それ以降は簡単に変更することができます。

また、親クラスのメソッドに共通コードを配置してから、拡張クラスのrun()メソッドから$thisというメソッドを呼び出すこともできます。

しかし、私の質問は、これを行うための良い方法がありますか、または$thisキーワードを使用するか、各クラスのコードに貼り付ける必要がありますか?ここで

は、私は私の現在の考えで何をしたいかの小さな例です。

abstract class Parent_Class { 
    public abstract function run(); 

    protected function common_code() { 
     // Common code here 
    } 
} 

class Child_Class { 
    public function run() { 
     // Code here 
     // I want some common code to run after the run method has been called 

     $this->common_code(); // Is this the best way to do it? 
    } 
} 

それとも、何とかrun()メソッドが自動的にcommon_code()方法を実行するために呼び出されたときにというクラスを伝えることが可能です?

答えて

2

これを行うもっと簡単な方法は、単にrun()を呼び出し、次にcommon_code()を呼び出す3番目のメソッドを用意することです。サブクラスでは、run()をすべてオーバーライドできます。

abstract class Parent_Class { 
    public abstract function run(); 

    protected function common_code() { 
     // Common code here 
    } 

    protected function start() { 
     $this->run(); 
     $this->common_code(); 
    } 

} 

class Child_Class { 
    public function run() { 
     // Code here 
    } 
} 
+0

からそのメソッドを実行することができます - 私はこの質問を残しておきます...私はそれを考えていなかったと信じてすることはできません他の誰かがいろいろな提案をしているかどうかを少し見てみてください。しかしあなたの答えを読んだら、今はとても分かりそうです。 –

1

アンバーが与えた答えは素晴らしく簡単です。ただし、run()にデータを入力する必要がありますが、start()に電話する必要があります。あなたのコードにすべてのスクリプトに$a->run()というコードを付けることができ、$a->run()に共通コードを使用する代わりに、名前空間にカプセル化する方法があります。

ファイルhooks.php

<?php 
// File: hooks.php 
namespace hook; 

class processHooks { 
    public function __construct() { /* Fatal Error without constructor */ } 

    protected function processHooks($_c, $method, $args) { 
     /* Swap the next two callbacks to run your custom code after */ 
     call_user_func_array("\hook\\{$_c}::{$method}", $args); 
     return call_user_func_array(array($_c,$method), $args); 
    } 
} 

class A { 
    public function foo() { 
     echo 'Doing code stuff BEFORE calling child function....<br>'; 
    } 
} 

ファイルregular_file.phpそれはないですので、これは、にregular_file.phpが保護されているクラス方法fooのbeacause作品

<?php 
// File: regular_file.php 
include "hooks.php"; 

class A extends \hook\processHooks { 

    /* All that is required is this function 
    * and the function with common code to be protected 
    */ 
    public function __call($method, $args) { 
     self::processHooks(__CLASS__, $method, $args); 
    } 

    protected function foo() { 
     echo 'Method is called....<br>'; 
    } 
} 

$a = new A(); 
$a->foo(); 

クラスの外側で呼び出し可能なので、PHPマジックメソッドを呼び出すと、__call

オブジェクトコンテキストでアクセスできないメソッドを呼び出すと、__call()がトリガされます。

+0

これは、すべての静的関数を使用して設計したシステムの簡略化されたバージョンです。使用したい場合は、簡単に元に戻すことができます。 – Bradmage

1

保護としてブラッドリーフォースターの回答に基づいて、あなたがメソッドを定義することができますので、それはクラスの外から呼ばれていたとき、あなたは、PHPの魔法__call metodでイベントをインターセプトすることができ__call(

ため)でありますオブジェクトコンテキストでアクセスできないメソッドを呼び出すときにトリガされます。

、その後、あなたは__call機能は非常に良い点だ

class A { 

    public function __call($method, $args){ 

    if(!method_exists($this, $method)) 
     throw new Exception("Call to undefined method ".__CLASS__."::$method()"); 

    echo "doing something BEFORE function 'run' execution\n"; 

    $retval = call_user_func_array(array($this, $method), $args); 

    echo "doing something AFTER function 'run' execution\n"; 

    return $retval; 
    } 

    protected function run() { 
     echo "function 'run' executed\n" ; 
    } 
} 

$a = new A; 
$a->run(); 
関連する問題