我如何从 JSON 字符串变量中解析 php 函数?

How can i parse php functions from JSON string variable?

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

$str = '"field_table_id": {
    "element_name": "select",
    "title": "some_title",
    "attributes": {
        "id": "field_table_id"
    },
    "options": {
        "values" : "@php_function ['function1', 'arg1', 'arg2', 'arg3'] @end_php",
        "titles" : "@php_function ['function1', 'arg1', 'arg2', 'arg3'] @end_php"
    }
}';

我该怎么做?

当我问这个问题时,我认为以下答案是正确的,但我现在找到了更好的解决方案。
我为此写了一个简单的函数。你可以在你的代码中使用这个函数。

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);

我的新解决方案是:
在 JSON 语法中,大括号包含对象,方括号包含数组,假设我将 JSON 更改为以下字符串:

{
    "field_table_id": {
        "element_name": "select",
        "title": "programming lanquages",
        "attributes": "json_object('element_attrs')",
        "options": {
            "values" : "json_array('options_values')"
        }
    }
}

我要替换

json_object('element_attrs')

使用像这样的 PHP 数组作为 JSON 对象:

array('id' => 'select1', 'value' => 'php', 'style' => 'width:30%')

json_array('options_values')

将此 PHP 数组作为 JSON 数组:

array('php', 'html', 'js', 'jquery')

下面的 PHP 函数对我们来说是这样的

function readOurJson( string $json_path, array $replaces = array() ) {
    if ( is_file($json_path) ) {
        $json_string = file_get_contents( $json_path );
    } else {
        return false;
    }
    $json_string = preg_replace_callback(
        '/\"(json_array|json_object)\(\'([a-zA-Z]+[0-9a-zA-Z_]*)\'\)\"/m',
        function ($matches) use ($replaces) {
            if ( ! empty($matches) ) {
                $key = $matches[2];
                switch ( $matches[1] ) {
                    case 'json_array' :
                        if ( isset($replaces[$key]) ) {
                            if ( is_array($replaces[$key]) ) {
                                $json_array = '"' . implode( '","', $replaces[$key] ) . '"';
                                return "[$json_array]";
                            }
                        }
                    case 'json_object' :
                        if ( isset($replaces[$key]) ) {
                            if ( is_array($replaces[$key]) ) {
                                $json_object = json_encode($replaces[$key]);
                                return $json_object;
                            }
                        }
                }
                return $matches[0];
            }
        },
        $json_string
    );
    return json_decode($json_string);
}

用法:

$replaces = array(
    'element_attrs' => array('id' => 'select1', 'value' => 1, 'style' => 'width:30%'),
    'options_values' => array('php', 'html', 'js', 'jquery')
);
$array = readOurJson( $json_path, $replaces);
var_dump($array);

Test Code on PHP Sandbox
如果您有任何建议或更正,请告诉我。

我在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)检查是否需要。