这是一段代码:
$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;
那么,在第一段代码中,发生了什么?此外,大括号的功能是什么?他们告诉编译器怎么想?
答案 0 :(得分:10)
$obj->{$_GET["func"]}($_GET["param"])
只需调用名称存储在$ _GET [“func”]中的方法,并作为参数$ _GET [“param”]传递。
括号用于消除方法名称的歧义(出于类似目的,您还在字符串中使用括号,例如echo "calling {$_GET['func']}";
有关详情,请参阅PHP manual page on variable variables,例如
为了使用变量变量 对于数组,你必须解决一个问题 歧义问题。也就是说,如果你 写
$$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
数组!
答案 1 :(得分:1)
它基本上是根据参数调用函数。
所以,如果您提出的请求如下:
mypage.php?func=prop¶m=value
你最终会得到这个函数调用:
$obj->prop('value')
大括号用于将数组符号保持在一起并将[[func]]应用于$ _GET变量而不是$ obj-> $ _ GET(可能是有效数组)。如果您没有使用大括号,那么您将要做的是:
($obj->$_GET)["func"](...)
在这种情况下,请注意您将要求数组$ obj-> $ _ GET的键“func”,而不是$ _GET。