Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it bad practice to use variable variables in PHP?

For example, a simple MVC type system:

/api/class/method rewritten into PHP variables using .htaccess/nginx.conf, then doing something like:

<?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
}

?>

Is this horribly bad practice? If it is bad practice, can someone explain exactly why? And if so, is there a better way to do what I'm doing?

EDIT Essentially the reason I'm using variable variables is to make it simple to expand the core system - i.e. - adding in a new controller is nice and simple. I definitely understand the security risks of allowing essentially any function or class to be instantiated without some kind of filter.

The 'some_filter_here' could be a list of controllers that are allowed - whitelist as some here have mentioned.

like image 491
Jonathan Coe Avatar asked Feb 21 '23 23:02

Jonathan Coe


2 Answers

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.

like image 92
cmbuckley Avatar answered Feb 24 '23 14:02

cmbuckley


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.

like image 31
Oomta Avatar answered Feb 24 '23 12:02

Oomta