duanpiangeng8958 2011-02-28 14:16
浏览 46

在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

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

something to say

instead of

something
  • 写回答

3条回答 默认 最新

  • douce1368 2011-02-28 14:21
    关注

    perhaps something like this:

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

    However, eval() is evil and should be avoided at all costs.

    评论

报告相同问题?

悬赏问题

  • ¥20 mysql架构,按照姓名分表
  • ¥15 MATLAB实现区间[a,b]上的Gauss-Legendre积分
  • ¥15 Macbookpro 连接热点正常上网,连接不了Wi-Fi。
  • ¥15 delphi webbrowser组件网页下拉菜单自动选择问题
  • ¥15 linux驱动,linux应用,多线程
  • ¥20 我要一个分身加定位两个功能的安卓app
  • ¥15 基于FOC驱动器,如何实现卡丁车下坡无阻力的遛坡的效果
  • ¥15 IAR程序莫名变量多重定义
  • ¥15 (标签-UDP|关键词-client)
  • ¥15 关于库卡officelite无法与虚拟机通讯的问题