Voici ma méthode pour imiter les décorateurs de python en php.
function call_decorator ($decorator, $function, $args, $kwargs) {
// Call the decorator and pass the function to it
$decorator($function, $args, $kwargs);
}
function testing ($args, $kwargs) {
echo PHP_EOL . 'test 1234' . PHP_EOL;
}
function wrap_testing ($func, $args, $kwargs) {
// Before call on passed function
echo 'Before testing';
// Call the passed function
$func($args, $kwargs);
// After call on passed function
echo 'After testing';
}
// Run test
call_decorator('wrap_testing', 'testing');
Sortie:
Before testing
testing 1234
After testing
Avec cette implémentation, vous pouvez aussi faire quelque chose comme ça avec une fonction anonyme:
// Run new test
call_decorator('wrap_testing', function($args, $kwargs) {
echo PHP_EOL . 'Hello!' . PHP_EOL;
});
Sortie:
Before testing
Hello!
After testing
Enfin vous peut même faire quelques chose comme ça, si vous êtes si incliné.
// Run test
call_decorator(function ($func, $args, $kwargs) {
echo 'Hello ';
$func($args, $kwargs);
}, function($args, $kwargs) {
echo 'World!';
});
Sortie:
Hello World!
Avec cette construction ci-dessus, vous pouvez passer des variables à la fonction interne ou un emballage, le cas échéant.Voici que la mise en œuvre d'une fonction interne anonyme:
$test_val = 'I am accessible!';
call_decorator('wrap_testing', function($args, $kwargs){
echo $args[0];
}, array($test_val));
Il fonctionnera exactement de la même sans une fonction anonyme:
function test ($args, $kwargs) {
echo $kwargs['test'];
}
$test_var = 'Hello again!';
call_decorator('wrap_testing', 'test', array(), array('test' => $test_var));
Enfin, si vous avez besoin de modifier la variable à l'intérieur soit l'enveloppe ou la wrappie, il suffit de passer la variable par référence.
Sans référence:
$test_var = 'testing this';
call_decorator(function($func, $args, $kwargs) {
$func($args, $kwargs);
}, function($args, $kwargs) {
$args[0] = 'I changed!';
}, array($test_var));
Sortie:
testing this
référence:
$test_var = 'testing this';
call_decorator(function($func, $args, $kwargs) {
$func($args, $kwargs);
}, function($args, $kwargs) {
$args[0] = 'I changed!';
// Reference the variable here
}, array(&$test_var));
Sortie:
I changed!
C'est tout ce que j'ai pour l'instant, c'est très utile dans beaucoup de cas, et vous pouvez même les emballer plusieurs fois si vous le souhaitez.
Votre exemple de Wrap_A est un peu trompeur pour quelqu'un qui ne sait pas déjà comment le travail de Python décorateur, puisque votre implémentation de Wrap_A référence explicitement A. L'idée d'un décorateur est que vous pouvez décorer n'importe quelle fonction avec, mais Dans votre exemple, vous ne pouvez pas utiliser 'Wrap_A' pour envelopper une autre fonction' B'. Cela vous dérangerait-il si je modifiais votre question pour en faire une représentation plus précise de la fonction de décoration? –