Ecco il mio metodo di imitare decoratori da Python in 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');
uscita:
Before testing
testing 1234
After testing
Con questa implementazione si può anche fare qualcosa di simile con una funzione anonima:
// Run new test
call_decorator('wrap_testing', function($args, $kwargs) {
echo PHP_EOL . 'Hello!' . PHP_EOL;
});
uscita:
Before testing
Hello!
After testing
E infine si può anche fare un po ' cosa del genere, se sei così inclinato.
// Run test
call_decorator(function ($func, $args, $kwargs) {
echo 'Hello ';
$func($args, $kwargs);
}, function($args, $kwargs) {
echo 'World!';
});
uscita:
Hello World!
Con questa costruzione sopra, è possibile passare variabili per la funzione interna o involucro, se necessario.Ecco che l'implementazione di una funzione interna anonima:
$test_val = 'I am accessible!';
call_decorator('wrap_testing', function($args, $kwargs){
echo $args[0];
}, array($test_val));
Funzionerà esattamente la stessa, senza una funzione anonima:
function test ($args, $kwargs) {
echo $kwargs['test'];
}
$test_var = 'Hello again!';
call_decorator('wrap_testing', 'test', array(), array('test' => $test_var));
Infine, se è necessario modificare la variabile all'interno sia l'involucro o la wrappie, devi solo passare la variabile per riferimento.
Senza riferimento:
$test_var = 'testing this';
call_decorator(function($func, $args, $kwargs) {
$func($args, $kwargs);
}, function($args, $kwargs) {
$args[0] = 'I changed!';
}, array($test_var));
uscita:
testing this
Con riferimento:
$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));
uscita:
I changed!
Questo è tutto ciò che ho per ora, è abbastanza utile in molti casi, e puoi anche copiarli più volte se lo desideri.
Il tuo esempio di Wrap_A è un po 'fuorviante per qualcuno che non sa già come funziona il decoratore Python, dal momento che la tua implementazione di Wrap_A fa esplicito riferimento a A. L'idea di un decoratore è che puoi decorare qualsiasi funzione con esso, ma in il tuo esempio non puoi chiaramente usare 'Wrap_A' per racchiudere qualche altra funzione' B'. Ti dispiacerebbe se avessi modificato la tua domanda per renderla una rappresentazione più accurata di cosa sia la decorazione della funzione? –