is it bad practice to use variable variables in php in the following fashion?

荒凉一梦 提交于 2019-12-05 16:25:06

Yes, this is rather bad practise. Do you need a variable variable for that instance? In other words, do you need more than one class & method to be instantiated in a given request? Your URI structure suggests not. If not, you could just use:

$object = new $className();
$object->$method();

Otherwise, you might want to do:

$objects = array();
$objects[$className] = new $className();
$objects[$className]->$method();

This avoids polluting the scope with variable variables, which are harder to track.

As far as the existence checks for your class in a given directory, this should be a sufficient whitelist (presuming an attacker cannot write to that directory).

EDIT: As a further check, you may want to consider checking method_exists on the object before calling the method.

Since you're writing the "some_class_filter" and "some_method_filter" code, I'd say it's OK. You also have a error or default handler I see, so in the end, I'd say it's alright.

I believe many MVC frameworks operate in a similar fashion anyway.

They're not desirable, but it's fine to use them how you have.

A couple of pointers, though: your code does have a vulnerability where an attacker could traverse your directory with $_GET parameters like ?class=../base. If that file exists, your file_exists() call will return true and your application will attempt to include it and instantiate it as a class.

The safe scenario would be to whitelist those parameters to be letters, numbers and underscores only (if you separate words with underscores, i.e. .php).

Also, I prefer the syntax of using call_user_func and call_user_func_array. Using these functions in your code would look as follows:

<?php
$class_name = $_GET['class'];
$method_name = $_GET['method'];

$parameters = $_GET;
unset($parameters['class'], $parameters['method']); // grabs any other $_GET parameters

if (file_exists(BASE.'/controllers/'.$class_name.'.class.php')) {
    require BASE.'/controllers/'.$class_name.'.class.php';
    $controller = new $class_name();
    $response = call_user_func_array(array($controller, $action_name), $parameters);
}
else {
    header('HTTP/1.1 404 Not Found');
    // ...and display an error message
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!