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