0

我想从字符串变量中提取和运行 PHP 函数。我的字符串变量是:

$str = "<h4>@php_function ['function1', 'arg1', 'arg2', 'arg3'] @end_php</h4>";

我怎样才能做到这一点?

4

2 回答 2

1

我已经用 PHP 编写了一个主题和模板系统,但是对于您所展示的内容,只是稍微更改 PHP 语法以再次将其更改回来是没有好处的。但是,如果您愿意使用双引号,["function1", "arg1", "arg2", "arg3"]那么您可以将其视为 JSON:

preg_match('/@php_function(.*)@end_php/', $str, $args);
$args = json_decode($args[1]);
$func = array_shift($args);

if(function_exists($func)) {
    $func(...$args);
} else {
    echo "$func not defined";
}

要保留单引号(如果混合使用它可能会中断):

$args = json_decode(str_replace("'", '"', $args[1]));

或将其评估为 PHP:

eval("\$args = {$args[1]};");

如果需要,只需添加in_array($func, $valid_functions)检查。

于 2021-05-22T17:59:09.473 回答
0

我为此编写了一个简单的函数。您可以在代码中使用此功能。

function php_function_parser( $string ) {
    $valid_functions = array( 'function1', 'function2' );
    $string = preg_replace_callback(
        '/@php_function(.*?)@end_php/m',
        function ($matches) {
            $usr_function = $matches[1];
            eval("\$usr_function = $usr_function;");
            if ( is_array($usr_function) ) {
                if ( in_array($usr_function[0], $valid_functions) ) {
                    $fnc_name = $usr_function[0];
                    array_shift($usr_function);
                    if ( is_array($usr_function) ) {
                        return call_user_func_array( $fnc_name, $usr_function );
                    } else {
                        return call_user_func( $fnc_name, $usr_function );
                    }
                } else {
                    return 'invalid or forbidden php function use';
                }
            }
        },
        $string
    );
    return $string;
}

用法:

$str = "<h4>@php_function ['function1', 'arg1', 'arg2', 'arg3'] @end_php</h4>";
echo php_function_parser($str);

如果您有任何建议或更正,请告诉我。

于 2021-05-22T17:23:51.280 回答