Here is my method of mimicking decorators from 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');
Output:
Before testing
testing 1234
After testing
With this implementation you can also do something like this with an anonymous function:
// Run new test
call_decorator('wrap_testing', function($args, $kwargs) {
echo PHP_EOL . 'Hello!' . PHP_EOL;
});
Output:
Before testing
Hello!
After testing
And lastly you can even do something like this, if you are so inclined.
// Run test
call_decorator(function ($func, $args, $kwargs) {
echo 'Hello ';
$func($args, $kwargs);
}, function($args, $kwargs) {
echo 'World!';
});
Output:
Hello World!
With this construction above, you can pass variables to the inner function or wrapper, if need be. Here is that implementation with an anonymous inner function:
$test_val = 'I am accessible!';
call_decorator('wrap_testing', function($args, $kwargs){
echo $args[0];
}, array($test_val));
It will work exactly the same without an anonymous function:
function test ($args, $kwargs) {
echo $kwargs['test'];
}
$test_var = 'Hello again!';
call_decorator('wrap_testing', 'test', array(), array('test' => $test_var));
Lastly, if you need to modify the variable inside either the wrapper or the wrappie, you just need to pass the variable by reference.
Without reference:
$test_var = 'testing this';
call_decorator(function($func, $args, $kwargs) {
$func($args, $kwargs);
}, function($args, $kwargs) {
$args[0] = 'I changed!';
}, array($test_var));
Output:
testing this
With reference:
$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));
Output:
I changed!
That is all I have for now, it is a pretty useful in a lot of cases, and you can even wrap them multiple times if you want to.
Wrap_A
to wrap some other functionB
. Would you mind if I edited your question to make it a more accurate representation of what function decoration is? – Envoy