在PHP闭包中注入代码

oxcyiej7  于 2023-05-21  发布在  PHP
关注(0)|答案(3)|浏览(141)

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

$predefined = "print 'my predefined injected code<br />';";
$closure = function () {
  print 'hello<br />';
};
call_user_func_array($closure, array());
// output : hello

我想混合两个代码:一个预定义的和一个闭包的。修改后,我希望我的闭包看起来像这样

$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
qni6mghb

qni6mghb1#

你不能直接注射。但是你可以把它包起来。

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

另外,由于没有传递任何参数,因此不需要使用call_user_func_array。就叫$closure();
另外,你可以构建一个 Package 器来获得一个新的闭包:

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

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

t9eec4r02#

也许是这样的

$closure = function($optionalcode = null) {
    print('blah blah blah');
    if (!is_null($optionalcode)) { eval($optionalcode); }
    print('blah blah blah');
}

$closure("print('yoohoo!');");

然而,eval()是邪恶的,应该不惜一切代价避免。

相关问题