在 PHP 闭包中注入代码
我有一个已经定义的闭包,我想在执行它时在其中注入代码。 这是一个示例:
$predefined = "print 'my predefined injected code<br />';";
$closure = function () {
print 'hello<br />';
};
call_user_func_array($closure, array());
// output : hello
我想混合 2 个代码:预定义的代码和闭包的代码。 修改后,我希望我的闭包看起来像这样
$closure = function () {
print 'my predefined injected code<br />';
print 'hello<br />';
};
是否可以在执行之前在闭包中插入一些代码?
注意:我不能使用将代码作为字符串的“create_function”,因此可以轻松修改。闭包已经定义并且以某种方式定义(通过采用回调参数而不是字符串参数的函数)。
感谢您的帮助。
编辑:
解决方案
function hackClosure($closure, $inject_code)
{
$reflection = new ReflectionFunction($closure);
$tmp = $reflection->getParameters();
$args = array();
foreach ($tmp as $a) array_push($args, '$'.$a->getName() . ($a->isDefaultValueAvailable() ? '=\''.$a->getDefaultValue().'\'' : ''));
$file = new SplFileObject($reflection->getFileName());
$file->seek($reflection->getStartLine()-1);
$code = '';
while ($file->key() < $reflection->getEndLine())
{
$code .= $file->current();
$file->next();
}
$start = strpos($code, '{')+1;
$end = strrpos($code, '}');
return create_function(implode(', ', $args), substr($code, $start, $end - $start) . $inject_code);
}
$theClosure = function () { print 'something'; };
$inject_code = "print ' to say';";
$func = hackClosure($theClosure, $inject_code);
$func();
这是它呈现的
something to say
而不是
something
I have an already defined closure and I want to inject code inside when I execute it.
Here is an example:
$predefined = "print 'my predefined injected code<br />';";
$closure = function () {
print 'hello<br />';
};
call_user_func_array($closure, array());
// output : hello
I want to mix 2 codes : a predefined one and the closure's one.
After modification, I want my closure to look like this
$closure = function () {
print 'my predefined injected code<br />';
print 'hello<br />';
};
Is it possible to insert some code in the closure before executing it ?
Note: I can not use "create_function" that take the code as a string, so can be modified easily. The closures are already defined and are defined in a certain way (through a function that take a callback arg, not a string arg).
Thanks for your help.
EDIT:
Here is the solution
function hackClosure($closure, $inject_code)
{
$reflection = new ReflectionFunction($closure);
$tmp = $reflection->getParameters();
$args = array();
foreach ($tmp as $a) array_push($args, '
It renders
something to say
instead of
something
.$a->getName() . ($a->isDefaultValueAvailable() ? '=\''.$a->getDefaultValue().'\'' : ''));
$file = new SplFileObject($reflection->getFileName());
$file->seek($reflection->getStartLine()-1);
$code = '';
while ($file->key() < $reflection->getEndLine())
{
$code .= $file->current();
$file->next();
}
$start = strpos($code, '{')+1;
$end = strrpos($code, '}');
return create_function(implode(', ', $args), substr($code, $start, $end - $start) . $inject_code);
}
$theClosure = function () { print 'something'; };
$inject_code = "print ' to say';";
$func = hackClosure($theClosure, $inject_code);
$func();
It renders
instead of
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你不能直接注入它。但是,您可以将其包裹起来。
此外,无需使用
call_user_func_array
因为您没有传递任何参数。只需调用$closure();
另外,您可以构建一个包装器来获取新的闭包:
You can't directly inject it. However, you can wrap it.
Also, there's no need to use
call_user_func_array
since you're not passing any arguments. Just call$closure();
Also, you could build a wrapper to get a new closure:
也许是这样的:
然而,
eval()
是邪恶的,应该不惜一切代价避免。perhaps something like this:
However,
eval()
is evil and should be avoided at all costs.这不是您要找的吗? http://php.net/manual/en/function.eval.php
Is't this what you are looking for ? http://php.net/manual/en/function.eval.php