Here is my method of imitating 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 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 finally, you can even do something like that if you are so addicted.
// 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 an internal function or shell, if necessary. Here is this implementation with an anonymous internal 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));
Finally, if you need to change a variable inside a wrapper or wrapper, you just need to pass the variable by reference.
No 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 a link:
$test_var = 'testing this'; call_decorator(function($func, $args, $kwargs) { $func($args, $kwargs); }, function($args, $kwargs) { $args[0] = 'I changed!';
Output:
I changed!
That's all I have at the moment, in many cases it is very useful, and you can even wrap them several times if you want.