以下列方式在php中使用变量变量是不好的做法吗?

Jon*_*Coe 4 php variables class variable-variables

例如,一个简单的mvc类型系统:

/ api/class/method使用.htaccess/nginx.conf重写为php变量

然后做类似的事情:

<?php

// Set up class + method variables
$className = some_class_filter($_GET['class']);
$method = some_method_filter($_GET['method']);

// Check if class exists and execute
if(file_exists(BASE . "/controllers/" . $className . ".class.php")) {
    require BASE . "/controllers/" . $className . ".class.php";
    $$className = new $className();

    // Execute the method
    $$className->$method();
} else {
    // Spit out some error based on the problem
}

?>
Run Code Online (Sandbox Code Playgroud)

这是非常糟糕的做法吗?如果这是不好的做法,有人可以解释为什么?如果是这样,有没有更好的方法来做我正在做的事情?

编辑基本上我使用变量变量的原因是为了简化核心系统的扩展 - 即 - 添加一个新的控制器很简单.我绝对理解允许基本上任何函数或类在没有某种过滤器的情况下实例化的安全风险.

'some_filter_here'可以是允许的控制器列表 - 白名单,正如这里提到的那样.

cmb*_*ley 6

是的,这是相当糟糕的做法.您是否需要该实例的变量变量?换句话说,您是否需要在给定的请求中实例化多个类和方法?你的URI结构不是.如果没有,你可以使用:

$object = new $className();
$object->$method();
Run Code Online (Sandbox Code Playgroud)

否则,您可能想要这样做:

$objects = array();
$objects[$className] = new $className();
$objects[$className]->$method();
Run Code Online (Sandbox Code Playgroud)

这避免了使用难以跟踪的变量变量来污染范围.

至于存在在给定目录中检查您的类的情况,这应该是足够的白名单(假设攻击者无法写入该目录).

编辑:作为进一步检查,您可能需要method_exists在调用方法之前考虑检查对象.