10
votes

La méthode magique de PHP __Call sur les sous-classes

Ma situation est décrite mieux avec un peu de code: xxx

Je sais que je peux obtenir ceci pour travailler en redéfinissant la barre () (et tous les autres Méthodes pertinentes) Dans la sous-classe, mais à mes fins, ce serait bien si la fonction __ appelle pourrait les gérer. Il suffit de faire des choses un lot nitre et plus gérable.

est-ce possible dans php?


0 commentaires

5 Réponses :


14
votes

__ appel () est uniquement invoqué lorsque la fonction n'est pas autrement trouvée, votre exemple n'est pas possible, comme écrit, n'est pas possible.


0 commentaires

2
votes

On ne peut pas être fait directement, mais c'est une alternative possible:

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);
    }
}


1 commentaires

Cette. Vous devez suivre le motif de la façade. Avoir une classe d'emballage qui "possède" l'objet que vous souhaitez remplacer toutes ces fonctions. Utilisez __Call () pour traverser des méthodes au besoin, effectuer des travaux supplémentaires, le cas échéant. Ne transpirez pas la performance que si votre code n'est appelé constamment et que votre application est limitée par la CPU (presque jamais le cas) - l'heure de programmeur est presque toujours plus importante que la performance lors de la décision de ce type de compromis.



0
votes

Si vous devez ajouter quelque chose de plus à la barre des parents (), cela serait-ce que cela serait faisable? XXX

ou est-ce juste une question de curiosité?


2 commentaires

Le problème découle du fait que la classe mère pourrait avoir un tas de fonctions et je ne veux pas avoir à les dupliquer dans la sous-classe, juste pour appliquer le même comportement (le // faire autre chose premier partie) à tous


@NICKF Absolument, cela me semble comme si nécessaire, je ne comprends pas pourquoi ce n'est pas dans PHP.



0
votes

Ce que vous pouvez faire pour avoir le même effet est le suivant:

    <?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."

?>


0 commentaires

2
votes

Une chose que vous pouvez essayer est de définir vos fonctions de périmètre à privé ou protégé. Lorsqu'une fonction privée est appelée de l'extérieur de la classe, il appelle la méthode de magie __Call et vous pouvez l'exploiter.


1 commentaires

Top réponse sous-estimé.