【问题标题】:Dynamically Create Functions with Eval() in PHP在 PHP 中使用 Eval() 动态创建函数
【发布时间】:2012-09-19 05:58:04
【问题描述】:

我正在尝试使用eval() 动态创建函数。但我收到了这个警告:Notice: Use of undefined constant 有什么建议吗?

$funcs = array('func_a', 'func_b', 'func_c');
foreach($funcs as $func_name) {
    eval( 'function ' . $func_name . '() { 
            mainfunc(' . $func_name . '); 
        }' 
    );  
}

func_a();
func_b();
func_c();

function mainfunc($func_name) {
    echo $func_name . '<br />';
}

假设数组$func 是一个存储在数据库中的选项值,我需要脚本的单独部分中的回调函数的函数名称。所以用create_function() 创建匿名函数不是我想要的。

感谢您的信息。

【问题讨论】:

  • mainfunc(' . $func_name . '); 行中,您需要将$func_name 括在引号中。就目前而言,该行变为mainfunc(func_a);
  • 这似乎是一个非常糟糕的主意。只是说。
  • 我认为在这种情况下没有必要动态创建函数。
  • 对于那些看不到它的必要性的人,有些情况需要将函数名称传递给自定义函数,该函数需要参数中的函数名称作为回调函数,例如 @ 987654330@ 在 WordPress 中。在基于唯一 ID 创建操作挂钩以在 WordPress 中调度后台进程时,根据保存的 ID 创建动态函数变得很有用。希望这是有道理的。

标签: php function syntax eval


【解决方案1】:

使用比 eval() 更好的方法,它被称为overloading

例子:

class MainFunc {

    public function __call($name, $arguments)
    {
        echo "_call($name)<br>";
    }

    public static function __callStatic($name, $arguments)
    {
        echo "_callStatic($name)<br>";
    }

}

# php >= 5.4.x
(new MainFunc)->func_a();
(new MainFunc)->func_b("param", "param2");
# or php < 5.4
$mainFunc = new MainFunc;
$mainFunc->func_a();
$mainFunc->func_b("param", "param2");

MainFunc::func_a_static();
MainFunc::func_b_static("param", "param2");

输出是:

_call(func_a)
_call(func_b)
_callStatic(func_a_static)
_callStatic(func_b_static)

【讨论】:

  • 很有趣,感谢您的意见。只是我的PHP版本不支持callStack()方法。
  • 那么不要使用__callStatic()。我刚刚演示了两种可能的解决方案。
  • __call() 似乎是要走的路。谢谢。
【解决方案2】:

您的评估正文需要阅读:

mainfunc(\'' . $func_name . '\'); 

没有单引号,eval() 使代码具有不带引号的文字——一个未定义的常量。

【讨论】:

    【解决方案3】:

    对于那些想知道我在说什么的人,这里是一个示例 WordPress 插件,它演示了动态函数创建是如何派上用场的。

    /* Plugin Name: Sample Action Hooks with Dynamic Functions */
    
    // assuming this is an option retrieved from the database
    $oActions = array(  'a' => array('interval' => 10, 'value' => 'hi'),
                        'b' => array('interval' => 30, 'value' => 'hello'),
                        'c' => array('interval' => 60, 'value' => 'bye')
                );  
    
    add_action('init', LoadEvents);
    function LoadEvents() {
        global $oActions;
        foreach($oActions as $strActionName => $array) {
            eval( 'function ' . $strActionName . '() { 
                        SampleEvents(\'' . $strActionName . '\'); 
                    }' 
            );  
            add_action('sampletask_' . md5($strActionName), $strActionName);
            if (!wp_next_scheduled( 'sampletask_' . md5($strActionName)))
                wp_schedule_single_event(time() + $oActions[$strActionName]['interval'], 'sampletask_' . md5($strActionName));                  
        }
    }
    function SampleEvents($strActionName) {
        global $oActions;
        // just log for a demo
        $file = __DIR__ . '/log.html';
        $current = date('l jS \of F Y h:i:s A') . ': ' . $strActionName . ', ' . $oActions[$strActionName]['value'] . '<br />' . PHP_EOL;
        file_put_contents($file, $current, FILE_APPEND);    
        wp_schedule_single_event(time() + $oActions[$strActionName]['interval'], 'sampletask_' . md5($strActionName));
    }
    

    __call() 可以实现相同的功能。

    /* Plugin Name: Sample Action Hooks */
    
    add_action('init', create_function( '', '$oSampleEvents = new SampleEvents;' ));
    class SampleEvents {
        public $oActions = array(   'a' => array('interval' => 10, 'value' => 'hi'),
                                    'b' => array('interval' => 30, 'value' => 'hello'),
                                    'c' => array('interval' => 60, 'value' => 'bye')
                            );
        function __construct() {                
            foreach($this->oActions as $strActionName => $arrAction) {
                add_action('sampletask_' . md5($strActionName), array(&$this, $strActionName));
                if (!wp_next_scheduled( 'sampletask_' . md5($strActionName)))
                    wp_schedule_single_event(time() + $this->oActions[$strActionName]['interval'], 'sampletask_' . md5($strActionName));
            }
        }
        function __call($strMethodName, $arguments) {
            // just log for a demo
            $file = __DIR__ . '/log.html';
            $current = date('l jS \of F Y h:i:s A') . ': ' . $strMethodName . ', ' . $this->oActions[$strMethodName]['value'] . '<br />' . PHP_EOL;
            file_put_contents($file, $current, FILE_APPEND);    
            wp_schedule_single_event(time() + $this->oActions[$strMethodName]['interval'], 'sampletask_' . md5($strMethodName));
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-13
      • 1970-01-01
      • 1970-01-01
      • 2017-05-28
      • 2012-05-27
      • 1970-01-01
      相关资源
      最近更新 更多