PHP和URL函数中的变量变量

时间:2009-03-17 12:59:30

标签: php variables

这是一段代码:

$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;

那么,在第一段代码中,发生了什么?此外,大括号的功能是什么?他们告诉编译器怎么想?

2 个答案:

答案 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&param=value

你最终会得到这个函数调用:

$obj->prop('value')

大括号用于将数组符号保持在一起并将[[func]]应用于$ _GET变量而不是$ obj-> $ _ GET(可能是有效数组)。如果您没有使用大括号,那么您将要做的是:

($obj->$_GET)["func"](...)

在这种情况下,请注意您将要求数组$ obj-> $ _ GET的键“func”,而不是$ _GET。