这是我在 php 中模仿 python 装饰器的方法。
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');
输出:
Before testing
testing 1234
After testing
使用此实现,您还可以使用匿名函数执行以下操作:
// Run new test
call_decorator('wrap_testing', function($args, $kwargs) {
echo PHP_EOL . 'Hello!' . PHP_EOL;
});
输出:
Before testing
Hello!
After testing
最后,如果你愿意的话,你甚至可以做这样的事情。
// Run test
call_decorator(function ($func, $args, $kwargs) {
echo 'Hello ';
$func($args, $kwargs);
}, function($args, $kwargs) {
echo 'World!';
});
输出:
Hello World!
使用上面的这种结构,如果需要,您可以将变量传递给内部函数或包装器。这是具有匿名内部函数的实现:
$test_val = 'I am accessible!';
call_decorator('wrap_testing', function($args, $kwargs){
echo $args[0];
}, array($test_val));
如果没有匿名函数,它将完全一样地工作:
function test ($args, $kwargs) {
echo $kwargs['test'];
}
$test_var = 'Hello again!';
call_decorator('wrap_testing', 'test', array(), array('test' => $test_var));
最后,如果您需要修改 wrapper 或 wrappie 中的变量,您只需要通过引用传递变量。
无参考:
$test_var = 'testing this';
call_decorator(function($func, $args, $kwargs) {
$func($args, $kwargs);
}, function($args, $kwargs) {
$args[0] = 'I changed!';
}, array($test_var));
输出:
testing this
供参考:
$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));
输出:
I changed!
这就是我现在所拥有的,它在很多情况下都非常有用,如果你愿意,你甚至可以多次包装它们。