0

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?

6
  • lol, you just asked the question and answered it at almost same time Commented May 22, 2021 at 17:28
  • This seems like you are trying to create a template, but it seems fairly inflexible. Yes you can call functions - but it looks like the parameters lack any real flexibility. Commented May 22, 2021 at 17:29
  • please let me know your suggestion about the parameters. Commented May 22, 2021 at 17:34
  • 1
    And why would you do this over "<h4><?php function1('arg1', 'arg2', 'arg3'); ?></h4>" ??? Commented May 22, 2021 at 17:42
  • @AbraCadaver yes we can use this too but with my method we can create our own HTML template. Commented May 22, 2021 at 17:48

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks a lot, simple and effective answer.I think you must switch from preg_match to preg_match_all function to extract all match.
Yes, this is just an example of shorter ways.
0

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 Comments

PHP Notice: Undefined variable: valid_functions
i have some html template and i use this function to extract and replace php function used in html template.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.