How can i parse php functions from JSON string variable?

185 views Asked by At

I want to extract and run PHP functions from a JSON string variable. my string variable is something like this :

$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"
    }
}';

how can I do this?

2

There are 2 answers

2
a.sadegh63 On BEST ANSWER

When I ask this question I think the following answer is right but I found a better solution now.
I write a simple function for this. you can use this function in your codes.

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

usage:

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

My new solution is :
In JSON syntax curly braces hold objects and square brackets hold arrays suppose I change the JSON to the following string :

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

I want replace

json_object('element_attrs')

with a PHP array like this as JSON object:

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

and

json_array('options_values')

with this PHP array as JSON array:

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

the following PHP function to this for us

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

usage:

$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
Let me know if you have any suggestions or corrections.

2
AbraCadaver On

I have written a theme and template system in PHP, but for what you show, just changing PHP syntax slightly to change it back again is not beneficial. However, if you are open to using double-quotes instead ["function1", "arg1", "arg2", "arg3"]then you can treat it as 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";
}

To stay with the single-quotes (it may break if you have a mix):

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

Or evaluate it as PHP:

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

Just add in_array($func, $valid_functions) check if needed.