爆炸字符串并调用动态函数

时间:2012-08-19 12:10:20

标签: php function dynamic explode

我有一个格式如下的字符串:

function1!!param1||ignore!!param2&&function2!!param1||ignore!!param2||ignore!!param3

它拥有的功能数量是无限的(它们用&&&分隔)

从上面的字符串生成的基本函数调用是:

function1($param1,$param2);

和第二个:

function2($param1,$param2,$param3);

params的数量是无限的。 (它们不是函数和param,只是一个例子)

很高兴回答任何问题!!我已经尝试过&& amp;然后 !!但我无法弄清楚如何用动态参数调用动态函数。

5.2的解决方案:

function function1( $a1, $a2 ) {
    echo $a1 . $a2;
}

function function2( $a1, $a2, $a3 ) {
    echo " ".$a1 . $a2 . $a3;
}
function explodemap($val) {
        $explode = explode( "!!", $val );
        return $explode[1];
}
$functions = explode( "&&", 'function1!!param1||ignore!!param2&&function2!!param1||ignore!!param2||ignore!!param3' );

foreach( $functions as $function ) {
    $split = explode( "||", $function );
    $weird_excalmation_split = explode("!!", $split[0] );
    $params = array_slice( $split, 1 );

    $params = array_map( "explodemap", $params );

    $fn_name = $weird_excalmation_split[0];
    array_unshift( $params, $weird_excalmation_split[1]  );

    call_user_func_array( $fn_name, $params );
}

2 个答案:

答案 0 :(得分:2)

使用call_user_func_array

function function1( $a1, $a2 ) {
    echo $a1 . $a2;
}

function function2( $a1, $a2, $a3 ) {
    echo $a1 . $a2 . $a3;
}

$functions = explode( "&&", 'function1!!param1||ignore!!param2&&function2!!param1||ignore!!param2||ignore!!param3' );

foreach( $functions as $function ) {
    $split = explode( "||", $function );
    $weird_excalmation_split = explode("!!", $split[0] );
    $params = array_slice( $split, 1 );

    $params = array_map( function($val) {
        return explode( "!!", $val )[1];
    }, $params );

    $fn_name = $weird_excalmation_split[0];
    array_unshift( $params, $weird_excalmation_split[1]  );

    call_user_func_array( $fn_name, $params );
}

//echoes param1param2param1param2param3

答案 1 :(得分:1)

在上面的评论中,我解释了为什么使用eval()是一个潜在的安全问题:

  

如果您从Android应用程序收到此数据,则表示您的   数据不安全,可能很容易被潜在的黑客改变。   如果您使用eval()执行收到的字符串,我可以调用每个   PHP函数通过更改函数名称。例如,如果我改变   您的字符串中function1exec("rm -rf /"); function1每个文件   将删除您的服务器,包括操作系统   (如果您的服务器上启用了exec()且您的服务器已启用   运行unix)。但你可以看到eval()有多危险,所以永远不要使用   它!


但是call_user_func_array()安全吗?

  

它更安全,但仍然不够安全。使用eval()我可以指定   功能名称和参数一起去,因为它简单   执行一个字符串。虽然这是不可能的   call_user_func_array(),它仍然执行任何指定的函数,   这意味着我仍然可以这样做。如果我将你的字符串更改为   exec!!rm -rf /你仍会遇到问题。真的,唯一的好处   方法是根据列入白名单的列表检查每个功能名称   名。


你怎么能让这个操作安全?您可以使用switch语句或in_array()来检查允许的功能。下面使用后者的一个例子:

<?php

// Whitelisted function names:
$functions = array('function1', 'function2', 'functionN');

// Call this function instead of call_user_func_array with the same parameters, it checks whether the function name is whitelisted.
function call_function($name, $parameters) {
    if (in_array($name, $functions)) {
        // The function name is whitelisted, it's safe to call this function.
        if (!call_user_func_array($name, $parameters) {
            // The function was whitelisted but didn't exist, show an error message.
        }
    } else {
        // A function was called that was not whitelisted! Write to log.
    }
}

?>

我没有测试它,但这应该有效。希望这有帮助!