这是一段代码:
$obj = new myClass();
$obj->{$_GET["func"]}($_GET["param"])
Run Code Online (Sandbox Code Playgroud)
它基于变量工作,但我真的不明白如何.据我所知,变量变量用于这样的东西:
require "dbsettings.php"
$member_id = $_GET['id'];
$db = new DBconnector();
$vars = array('username','passw','email','info','datejoined','dateofbirth');
foreach ($vars as $var) {
$$var = $db->getUserInfo($member_id,$var);
}
echo $username;
echo $passw;
echo $email;
echo $info;
echo $datejoined;
echo $dateofbirth;
Run Code Online (Sandbox Code Playgroud)
那么,在第一段代码中,发生了什么?此外,大括号的功能是什么?他们告诉编译器怎么想?
Pau*_*xon 10
$obj->{$_GET["func"]}($_GET["param"])
Run Code Online (Sandbox Code Playgroud)
只需调用名称存储在$ _GET ["func"]中的方法,并作为参数$ _GET ["param"]传递.
括号用于消除方法名称的歧义(出于类似目的,您还在字符串中使用括号,例如 echo "calling {$_GET['func']}";
为了将变量变量与数组一起使用,您必须解决模糊问题.也就是说,如果你编写,
$$a[1]那么解析器需要知道你$a[1]是否想要$$a用作变量,或者你想要作为变量,然后是该变量的[1]索引.解决这种歧义的语法是:${$a[1]}第一种情况和${$a}[1]第二种情况.
关于安全的说明
由于这是可接受的答案,我将补充一点,你不应该盲目地使用用户输入,$ obj上可能有你不想被调用的方法.
例如,您可以根据允许的方法数组检查方法名称,例如
$method=$_GET["func"];
$ok=in_array($method, array('foo', 'bar', 'frobozz'));
Run Code Online (Sandbox Code Playgroud)
或者,您只能允许遵循特定模式的方法名称,例如前缀为'ajax':
$method=$_GET["func"];
$ok=preg_match('/^ajax[A-Za-z]/', $method);
Run Code Online (Sandbox Code Playgroud)
或者是对该想法的变体,其中将前缀添加到传递的方法名称中,以便只能调用具有该前缀的方法
$method='ajax'.preg_replace('/[^A-Za-z]/', '', $_GET["func"]);
Run Code Online (Sandbox Code Playgroud)
还有其他方法,但希望这说明了一个基本原则:假设你最大的敌人构建$_GET阵列!