7 votes

php Définir une fonction anonyme dans une instance

Je débute en PHP, et je me demande s'il existe un moyen d'ajouter une fonction anonyme à une instance de classe.

Par exemple, disons...

class A{
    public B;
}

$c = new A();

//This is where I am getting a little confused...
//The following wont work

$c->B = function(){echo('HelloWorld');};
$c->B();

Ce que j'espère faire, c'est réutiliser le même bout de code dans un grand nombre d'applications différentes, et faire en sorte que je puisse simplement "échanger" et remplacer des fonctions dans des cas spécifiques.

J'utilise php5.3 (les fonctions anonymes devraient donc fonctionner, mais pas de la manière dont je les utilise).

Merci beaucoup pour votre temps !

-GK

10voto

Max Points 1397

Vous pouvez utiliser le __call fonction magique pour cet emploi. Pas une beauté, mais ça marche..

comme ça :

class A {
    public $B;

    public function __call($closure, $args)
    {
        call_user_func_array($this->$closure, $args);
    }
}

$c = new A();

$c->B = function () { echo('HelloWorld'); };
$c->B();

5voto

Charles Points 33585

POUR INFO :

Le traitement des fonctions anonymes par PHP 5.3 est amusant. Cela ne marchera pas :

$c->B = function() { echo func_get_arg(0); };
$c->B("This fails :(");

Ça va marcher :

$c->B = function() { echo func_get_arg(0); };
$hilarious = $c->B;
$hilarious("This works!");

Pour contourner ce problème, vous devez utiliser un fichier __call hack comme celui fourni par Oden .

Ce comportement mai changer à l'avenir. Le site RFC de déréférencement de tableau était récemment ajouté au tronc de PHP et le patch a déclenché une discussion sur enchaînement des appels de fonction dont la syntaxe peut permettre ce que vous essayez de faire sans le hack __call. Malheureusement, c'est s'est avéré difficile dans le passé pour que le chaînage des appels de fonction fonctionne.

4voto

user358390 Points 557
# real ugly, but PoC...

class a {
  function __call($f, $x) {
    call_user_func_array($this->$f, $x);
  }
}

$a = new a;
$a->b = function() { echo "Hello world"; };
$a->b();

2voto

Paul Dixon Points 122033

On dirait que vous décrivez un Modèle de stratégie o Motif décorateur - il y a otros moyens pour y parvenir d'une manière qui soit plus facilement communiquée aux autres développeurs qui lisent votre code.

1voto

Artefacto Points 50896

Vous pouvez faire quelque chose de ce genre (qui fonctionnera également avec des callbacks qui ne sont pas des fermetures) :

<?php
class A {
    private $fun;
    function setFun($fun) {
        if (!is_callable($fun))
            throw new InvalidArgumentException();
         $this->fun = $fun;
    }
    public function fun() {
        call_user_func_array($this->fun, func_get_args());
    }
}

$c = new A();

$c->setFun(function($a) { echo('HelloWorld ' . $a);});
$c->fun("here");

ce qui donne HelloWorld here .

Cela dit, vous devez également envisager l'héritage ou la motif décoratif .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X