动态地将代码传递给Closure / Anonymous函数

时间:2014-03-14 06:56:40

标签: php

我想用动态代码创建闭包。为此,我在下面写了代码: -

 function generateFunction ($class, $method){
    $code = "require_once 'Init.php';";
    $code = '$model = new '.$class.'();';
    $code .= '$model->'.$method.'();';

    return function() use(&$code){
       return eval($code);
    };
}

我知道eval是邪恶的,但却无法找到任何替代品。

要获取我在代码下面使用的变量中的函数: -

$myNewFunction = generateFunction ('svn', 'update');

现在我想通过将其作为参数传递给我的PHP文件来运行此函数。但是这个函数在输出上有相同的主体,而我预计它会像下面一样。

function(){return eval(require_once 'Init.php';$model = new svn(); $model->update())}

基本上,当我决定整合Jobby时会出现这种需求。

3 个答案:

答案 0 :(得分:1)

  

当我决定整合Jobby时,基本上会出现这种需求。

我假设你想动态创建回调函数。然后你的代码完全矫枉过正,根本不需要eval。您可以通过将其作为回调传递来获得相同的结果:

$callback = array(new SVN, 'update');

基本上你的所有代码都是这样做的。虽然区别在于SVN在此实例化,但不是在触发回调时。对于eval免费版本的代码,我们会这样做:

function generateFunction($class, $method) {
    return function () use ($class, $method) {
         require_once 'Init.php';
         $model = new $class;
         return $model->$method();
    };
}

答案 1 :(得分:1)

要完成您的答案,以下是jobby的完整示例:

$jobby = new \Jobby\Jobby();

$WebSitesSchedule = new WebSitesSchedule();
$WebSitesSchedule->load_all();

foreach ($WebSitesSchedule as $WebSiteSchedule)
{
    $Url = $WebSiteSchedule->ScheduleAction.'?'.$WebSiteSchedule->ScheduleParameters;

    $jobby->add( "CmsSchedule_".strval($WebSiteSchedule->ScheduleID), array(
        'command' => generateFunction($Url),
        'schedule' => $WebSiteSchedule->ScheduleCron,
        'output' => '/PATH/log/CmsSchedule.log',
        'enabled' => true,
        'debug' => true,
        'recipients' => 'toto@gmail.com'
    ));
}

function generateFunction($Url)
{
    return function () use ($Url)
    {
        $Result = Proxy::curl_request($Url);
        if($Result["status"]==="success")
        {
            print_r($Result);
            return TRUE;
        }
        else
        {
            print_r($Result);
            return FALSE;
        }

    };
}

$jobby->run();

答案 2 :(得分:0)

在您的情况下,您不需要使用eval()。您必须将call_user_func(或call_user_func_array)与class_existsmethod_exists结合使用。

require_once 'Init.php';
function generateFunction ($class, $method) {
    if (!class_exists($class)) return false;
    $model = new $class();
    return method_exists($model, $method)? array($model, $method) : false;
}

$myNewFunction = generateFunction ('svn', 'update');
if ($myNewFunction) call_user_func($myNewFunction);