Variable Variables in PHP - What Is Their Purpose

Variable variables in PHP - What is their purpose?

Sometimes we need software that is extremely flexible and that we can parametrize. You have to prepare the whole thing, of course, but part of it just comes from user input, and we have no time to change the software just because the user needs a new input.

With variable variables and variable functions you can solve problems that would be much harder to solve without them.

Quick Example:

Without variable variables:

$comment = new stdClass(); // Create an object

$comment->name = sanitize_value($array['name']);
$comment->email = sanitize_values($array['email']);
$comment->url = sanitize_values($array['url']);
$comment->comment_text = sanitize_values($array['comment_text']);

With variable variables

$comment = new stdClass(); // Create a new object

foreach( $array as $key=>$val )
{
$comment->$key = sanitize_values($val);
}

What's an actual use of variable variables?

Its purpose, I guess, is to allow novice programmers to dynamically change data without using "complicated stuff" like composite types (arrays and objects).

I never use them.

Why use dynamic variables (variable variables) in PHP or other languages

I had voted to close this question (vote since retracted) on the basis of it being subjective, but on reflection, I think I can give an objective answer.

A static variable name is a sequence of characters, representing a token which the underlying engine uses as a label to identify the value the variable represents (very very layperson's description).

A "sequence of characters" is a string. A string is an expression that represents a string. So from there it stands to reason that any expression that represents a string ought to be good enough to represent the token that refers to a variable. And that expression itself could be assigned to a variable, and from there one gets dynamic variable names.

But this is not what you asked. You asked: why?

It's not for the implementors of the language to answer questions like that. It's their job to provide a uniform and predictable programming interface, via their language. It's uniform to be able to represent a sequence of characters via an expression which in turn could be represented by a variable. Job done.

Subjectively, I could potentially see where some data is imported from an external source, and even the schema of the data is dynamic. One might want to represent that in some sort of generic object fashion, and it leads from there that the names of the properties of the object might also be dynamic. Whether or not this might be a good approach to the problem at hand is entirely subjective, and down to the developer's judgement, and that of their peers during code review.

Another example might be that you've inherited some shoddy spaghetti code where "needs must" and using dynamic naming - for whatever reason - might be a good approach.

PHP's burden ends at providing the mechanism to write the code; it does not speak to the quality of the design of said code. That's what code review is for.

what are the major advantages of using variable variables in php?

you can use it in case of not-user-input. Look

function getVar($gid){
$name = "gid".$gid;
global $$name;
$var = $$name;
return $var;
}

It's useful when you have a lot of variables (same start with ending number, etc...) which is probably save

When to use a variable variable in PHP?

One situation where I've had to use them is URI processing, although this technique might be dated, and I admittedly haven't used it in a long time.

Let's say we want to pull the URI from the script in the format domain.tld/controller/action/parameter/s. We could remove the script name using the following:

$uri_string = str_replace($_SERVER['SCRIPT_NAME'], '', $_SERVER['REQUEST_URI']);

To extract the controller, action, and parameter values from this we're going to have to explode the string using the path delimiter '/'. However, if we have leading or trailing delimiters, we'll have empty array values upon explosion, so we should trim those from the beginning and end of the string:

$uri_string = trim($uri_string, '/');

We can now explode the path into an array:

$uri_data = explode('/', $uri_string);

$uri_data[0] now contains our controller name, $uri_data[1] contains the action name, and values in the array beyond that are parameters that should be passed to the action method.

$controller_name = $uri_data[0];
$action_name = $uri_data[1];

So, now that we have these names, we can use them for a number of things. If you keep your controllers in a very specific directory relative to the site root, you can use this information to require_once the controller class. At that point, you can instantiate it and call it using variable variables:

$controller = new $controller_name();
$controller->{$action_name}(); // Or pass parameters if they exist

There are a lot of security gotchas to look out for in this approach, but this is one way I've seen to make use of variable variables.

DISCLAIMER: I'm not suggesting your actually use this code.

Variable variables as parameters of custom function in usort()

Resolving dynamic names of variables is something that happens at runtime, rather than interpreter (aka compile) time. Therefore, you can not pass it as dynamic paramaters which you expected to be able to do.

Given that, this is not possible for one simple reason: Even if you would manage to pass different names at compile time, it would only be true for one set of values to compare. What would keep the callback-call from passing a<b, then a>b, then a==b (imagine them as values)? Nothing, and exactly that would happen.

That being said, you can try and validate which value is smaller before passing it to the final callback, but this only adds an extra layer rather than always sorting the same way (or even sorting at all):

usort($dataset, function($a, $b)
{
if ($a > $b) {
return $b <=> $a;
}
return $a <=> $b;
});

var_dump($dataset);

// output
array(3) {
[0]=>
int(3)
[1]=>
int(1)
[2]=>
int(7)
}

I am fully aware that this does not solve your problem at all. I am just trying to demonstrate that it wont even work that way.

I think the key fact here is that you define the sort mechanism in your callback, and hence you have to make sure that you sort it ascending or descending in that definition, since that is what it exists for!

And on a side note I think sorting callbacks became really easy to create in PHP since the spaceship operator:

// defines: sort ASC
usort($dataset, function($a, $b) { return $a <=> $b; });
// defines: sort DESC
usort($dataset, function($a, $b) { return $b <=> $a; });

And even more so with the arrow functions since PHP 7.4:

// ASC
usort($dataset, fn($a, $b) => $a <=> $b);
// DESC
usort($dataset, fn($a, $b) => $b <=> $a);

In conclusion, I fully understand where you are coming from, but maybe you are trying to solve a problem that is not even really there?

variable-variables in PHP

  • $hash('foo') is a variable function.
    $hash may contain a string with the function name, or an anonymous function.

    $hash = 'md5';

    // This means echo md5('foo');
    // Output: acbd18db4cc2f85cedef654fccc4a4d8
    echo $hash('foo');
  • $$foo is a variable variable.
    $foo may contain a string with the variable name.

    $foo = 'bar';
    $bar = 'baz';

    // This means echo $bar;
    // Output: baz
    echo $$foo;
  • $bar[$foo] is a variable array key.
    $foo may contain anything that can be used as an array key, like a numeric index or an associative name.

    $bar = array('first' => 'A', 'second' => 'B', 'third' => 'C');
    $foo = 'first';

    // This tells PHP to look for the value of key 'first'
    // Output: A
    echo $bar[$foo];

The PHP manual has an article on variable variables, and an article on anonymous functions (but I didn't show an example above for the latter).



Related Topics



Leave a reply



Submit