本文介绍了在PHP闭包中注入代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个已经定义的闭包,我想在我执行它时注入代码。
这里是一个例子:

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

我想混合2个代码:闭合的一个。
修改后,我希望我的关闭看起来像这样

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 ?

注意:我不能使用create_function将代码作为字符串,所以可以很容易地修改。闭包已经定义并以某种方式定义(通过接受回调arg,而不是字符串arg的函数)。

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).

感谢您的帮助。

编辑:

>

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, '$'.$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


推荐答案

您不能直接注入它。

$newClosure = function() use ($closure) {
    print 'my predefined injected code<br />';
    $closure();
};

此外,也不需要使用 call_user_func_array 因为你没有传递任何参数。只需调用 $ closure();

Also, there's no need to use call_user_func_array since you're not passing any arguments. Just call $closure();

同样,你可以构建一个包装器来获得一个新的闭包: p>

Also, you could build a wrapper to get a new closure:

$creator = function($closure) {
    return function() use ($closure) {
        print 'my predefined injected code<br />';
        $closure();
    };
};

$newClosure = $creator($closure);
$newClosure();

这篇关于在PHP闭包中注入代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-24 03:01