Php 分解字符串并调用动态函数
我有一个如下格式的字符串:Php 分解字符串并调用动态函数,php,function,dynamic,explode,Php,Function,Dynamic,Explode,我有一个如下格式的字符串: function1!!param1||ignore!!param2&&function2!!param1||ignore!!param2||ignore!!param3 它拥有的函数数量是无限的(它们用&&&分割) 从上面的字符串生成的基本函数调用是: function1($param1,$param2); 第二个: function2($param1,$param2,$param3); 参数的数量是无限的。(它们不被调用函数和参数,这只是一个示
function1!!param1||ignore!!param2&&function2!!param1||ignore!!param2||ignore!!param3
它拥有的函数数量是无限的(它们用&&&分割)
从上面的字符串生成的基本函数调用是:
function1($param1,$param2);
第二个:
function2($param1,$param2,$param3);
参数的数量是无限的。(它们不被调用函数和参数,这只是一个示例)
很高兴回答任何问题!!我已经试过了&&然后!!但我不太明白如何使用动态参数调用动态函数
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 );
}
使用:
在上面的评论中,我解释了为什么使用
eval()
是一个潜在的安全问题:
如果您从Android应用程序收到此数据,则表示您的
数据不安全,很容易被潜在的黑客更改。
如果您使用eval()
执行收到的字符串,我可以每隔一天调用
通过更改函数名来创建PHP函数。例如,如果我改变
function1
在字符串中添加到exec(“rm-rf/”);功能1
每个文件
将删除服务器上的,包括操作系统
(前提是您在服务器上启用了exec()
,并且您的服务器
运行unix)。但是你可以看到eval()
有多危险,所以千万不要使用
它
但是
调用用户函数数组()
安全吗
它更安全,但仍然不够安全。使用eval()
我可以指定
函数名和参数一气呵成,因为
执行一个字符串。虽然这是不可能的
调用\u user\u func\u array()
,它仍然执行任何指定的函数,
这意味着我仍然可以做同样的事情。如果我能把你的字符串改成
exec!!rm-rf/
您仍然会遇到问题。真的,唯一好的
方法是对照白名单检查每个函数名
名字
你怎样才能保证这次行动的安全?您可以使用
开关
语句或\u 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.
}
}
?>
我没有测试它,但这应该是有效的。希望这有帮助 你可能不需要我告诉你这是一个非常糟糕的模式,但也许你继承了它。你不会说什么ignore
做了什么…谢谢你的回答。我正在通过http post从一个android应用程序发送一个字符串,该应用程序存储用户离线时所做的所有事情。如果你知道一个更好的方法,我真的很高兴听到。我对我存储数据的方式也不是很满意。。。。(你是否否决了我的意见?)看一看,显然你必须不止一次地应用它,然后才能看到如何调用存储在字符串中的函数名。忽略是字符串中我在函数调用中不需要的其他内容。看看我的第一条评论。当用户在线时,我使用相同的模式,只是每个| |都是一个http post参数:?function1=param1&someignore=param2tank you@Havelock和所有其他给我提示的参数。将使用你们提供给我的信息,然后重试。按指定方式工作。。。有什么问题吗?谢谢!!看起来不错。如果你的答案有效,我会接受你的答案并试着理解它。它需要PHP5.4,如果你有较低的版本,它就必须重写一点。@Lorof PHP5.4是explode(!!“,$val)[1]
(在早期的PHP中不能直接数组访问)所必需的,PHP5.3是传递给array\u map
的匿名函数所必需的。你可以重写5.2版。主要的一点是call\u user\u func\u array
,它是从PHP4或其他版本开始工作的。添加了5.2的解决方案。非常感谢你。
<?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.
}
}
?>