10

私の状況は、少しのコードで最もよく説明されています。

class Foo {
    function bar () {
        echo "called Foo::bar()";
    }
}

class SubFoo extends Foo {
    function __call($func) {
        if ($func == "bar") {
            echo "intercepted bar()!";
        }
    }
}

$subFoo = new SubFoo();

// what actually happens:
$subFoo->bar();    // "called Foo:bar()"

// what would be nice:
$subFoo->bar();    // "intercepted bar()!"

サブクラスで(および他のすべての関連メソッドを)再定義することでこれを機能させることができることはわかってbar()いますが、私の目的では、__call関数がそれらを処理できると便利です。それは物事をよりきちんと管理しやすくするだけです

これはPHPで可能ですか?

4

5 に答える 5

14

__call()関数が他の方法で見つからない場合にのみ呼び出されるため、記述されているように、例は使用できません。

于 2009-10-08T01:45:42.923 に答える
2

直接行うことはできませんが、これは1つの可能な代替手段です。

class SubFoo { // does not extend
    function __construct() {
        $this->__foo = new Foo; // sub-object instead
    }
    function __call($func, $args) {
        echo "intercepted $func()!\n";
        call_user_func_array(array($this->__foo, $func), $args);
    }
}

この種のことはデバッグとテストには適していますが__call()、本番コードではあまり効率的ではないため、できるだけ多くの人と友達にならないようにする必要があります。

于 2009-10-08T01:50:53.303 に答える
2

試すことができることの1つは、関数のスコープをプライベートまたは保護に設定することです。クラスの外部から1つのプライベート関数が呼び出されると、それは__callマジックメソッドを呼び出し、それを利用できます。

于 2016-04-05T13:00:09.867 に答える
0

同じ効果を得るためにできることは次のとおりです。

    <?php

class hooked{

    public $value;

    function __construct(){
        $this->value = "your function";
    }

    // Only called when function does not exist.
    function __call($name, $arguments){

        $reroute = array(
            "rerouted" => "hooked_function"
        );

        // Set the prefix to whatever you like available in function names.
        $prefix = "_";

        // Remove the prefix and check wether the function exists.
        $function_name = substr($name, strlen($prefix));

        if(method_exists($this, $function_name)){

            // Handle prefix methods.
            call_user_func_array(array($this, $function_name), $arguments);

        }elseif(array_key_exists($name, $reroute)){

            if(method_exists($this, $reroute[$name])){

                call_user_func_array(array($this, $reroute[$name]), $arguments);

            }else{
                throw new Exception("Function <strong>{$reroute[$name]}</strong> does not exist.\n");
            }

        }else{
            throw new Exception("Function <strong>$name</strong> does not exist.\n");
        }

    }

    function hooked_function($one = "", $two = ""){

        echo "{$this->value} $one $two";

    }

}

$hooked = new hooked();

$hooked->_hooked_function("is", "hooked. ");
// Echo's: "your function is hooked."
$hooked->rerouted("is", "rerouted.");
// Echo's: "our function is rerouted."

?>
于 2009-12-27T01:49:18.460 に答える
0

親bar()に何かを追加する必要がある場合、これは実行可能でしょうか?

class SubFoo extends Foo {
    function bar() {
        // Do something else first
        parent::bar();
    }
}

それとも、これは好奇心からの質問ですか?

于 2009-10-08T02:21:04.263 に答える