PHP Variable Variables

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);
}

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.

PHP - Difference in creating variable variables with brackets or double dollar signs?

Both versions are basically the same.

The curly braces notation is used in cases where there could be ambiguity:

$foo = 'bar';
$bar = [];
${$foo}[] = 'foobar';

var_dump($bar); // foobar

If you'd omit the braces in the above example, you'd get a fatal error, with the braces, it works fine.

However, I would recommend avoiding dynamic variable names altogether. They are funny to use and may save some space. But in the end, your code will become less readable and you will have trouble debugging.

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.

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?

PHP variable variable not overriding original variable

PHP documentation says

In order to use variable variables with arrays, you have to resolve an ambiguity problem. That is, if you write $$a[1] then the parser needs to know if you meant to use $a[1] as a variable, or if you wanted $$a as the variable and then the [1] index from that variable. The syntax for resolving this ambiguity is: ${$a[1]} for the first case and ${$a}[1] for the second.

So, you should use

${$_GET['schedule_test']}

However, I would strongly advise against using user input directly to decide which variable to write like this. There is a very high risk of allowing attackers to change the internal behaviour of your code.

Variable variables as array in php

You need to use another variable:

$maths5 = array(
array(
'csv'=>'file.csv',
'title'=>"Number and Place Value",
)
);

$var = "maths5";
$var2 = $$var;

echo $var2[0]['csv'];

PHP Variable Variables with array key

The following is an example following your variable name syntax that resolves array members as well:

// String that has a value similar to an array key
$string = 'welcome["hello"]';

// initialize variable function (here on global variables store)
$vars = $varFunc($GLOBALS);

// alias variable specified by $string
$var = &$vars($string);

// set the variable
$var = 'World';

// show the variable
var_dump($welcome["hello"]); # string(5) "World"

With the following implementation:

/**
* @return closure
*/
$varFunc = function (array &$store) {
return function &($name) use (&$store)
{
$keys = preg_split('~("])?(\\["|$)~', $name, -1, PREG_SPLIT_NO_EMPTY);
$var = &$store;
foreach($keys as $key)
{
if (!is_array($var) || !array_key_exists($key, $var)) {
$var[$key] = NULL;
}
$var = &$var[$key];
}
return $var;
};
};

As you can not overload variables in PHP, you are limited to the expressiveness of PHP here, meaning there is no write context for variable references as function return values, which requires the additional aliasing:

$var = &$vars($string);

If something like this does not suit your needs, you need to patch PHP and if not an option, PHP is not offering the language features you're looking for.

See as well the related question: use strings to access (potentially large) multidimensional arrays.



Related Topics



Leave a reply



Submit