I was just recently introduced to the concept of dynamic variables in PHP. To me it seems like using dynamic variables in a program would make it difficult to read/follow.
Can anyone explain to me the benefits and/or share a real simple real world example of when a dynamic variable in PHP might be needed?
If your wondering what dynamic variables are and how they work check out this question
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.
A variable variable
, is just another form of reflection. You are basically asking "Why would you ever want to change a variable, if you don't know it before runtime".
Although technically not the same, you could see a variable variable
as a different kind of hash table
(or array
in php). Most variable variables
could be rewritten as a hash table
, and you would not be surprised. But if you need to work with a variable before and after runtime, a hash table
might even be more awful to work with.
A simple use case might be settings that can be changed by a user. Keep in mind the following example is insecure as is, but demonstrates it's purpose.
<?php
/*
Simple way, if you have a limited amount of settings
*/
$settings = array();
$settings["allowAccess"] = 1;
$settings["allowModify"] = 1;
$settings["allowDelete"] = 0;
if ($result = $mysqli->query("SELECT `allowAccess`, `allowModify`, `allowDelete` FROM `user_settings` LIMIT 1"))
{
$row = $result->fetch_array(MYSQLI_ASSOC);
$settings["allowAccess"] = $row["allowAccess"];
$settings["allowModify"] = $row["allowModify"];
$settings["allowDelete"] = $row["allowDelete"];
}
/*
Now consider you have a thousand settings and you dont want to write out every setting manually.
*/
if ($result = $mysqli->query("SELECT * FROM `user_settings` LIMIT 1"))
{
$row = $result->fetch_array(MYSQLI_ASSOC);
foreach($row as $key => $val) {
$settings[$key] = $val;
}
}
/*
Both options work, but everytime you want to use a setting you have to use something like below
*/
if ($settings["allowAccess"] && $settings["allowModify"] && $settings["allowDelete"]) {
unlink($somefile);
}
/*
Perhaps you would rather write
*/
if ($allowAccess && $allowModify && $allowDelete) {
unlink($somefile);
}
/*
Then you can use
*/
if ($result = $mysqli->query("SELECT * FROM `user_settings` LIMIT 1"))
{
$row = $result->fetch_array(MYSQLI_ASSOC);
foreach($row as $key => $val) {
//if you use extract, all columns are extracted, unless you drop them first. But perhaps you need those for something else.
//now I extract the columns that start with allow and keep the columns like id, created, modified, etc. without the need to specify each column manually, which makes it easier if you ever decide to add another setting column. You don't need to update this part of the code.
if (substr($key,0,5)=='allow') {
$$key = $val; //$key = 'allowAccess', $$key == $allowAccess = $val;
}
}
}
?>
This is just one example, I found another example in the XHTML sanitizer for MediaWiki
by Brion Vibber
. He uses a lot of arrays in his code and at one point he needed to flip them all. He used the code below:
<?php
$vars = array( 'htmlpairs', 'htmlsingle', 'htmlsingleonly', 'htmlnest', 'tabletags',
'htmllist', 'listtags', 'htmlsingleallowed', 'htmlelements' );
foreach ( $vars as $var ) {
$$var = array_flip( $$var );
}
?>
Now obviously he could have written the code below, but is that really easier to read?
<?php
$htmlpairs = array_flip($htmlpairs);
$htmlsingle = array_flip($htmlsingle);
$htmlsingleonly = array_flip($htmlsingleonly);
$htmlnest = array_flip($htmlnest);
$tabletags = array_flip($tabletags);
$htmllist = array_flip($htmllist);
$listtags = array_flip($listtags);
$htmlsingleallowed = array_flip($htmlsingleallowed);
$htmlelements = array_flip($htmlelements);
?>
Which also introduces another use case: What if I wanted to dynamically decide which arrays to flip? In the variable variable
way, I can just push items onto the array and flip them when the time comes, In the "normal" way I would need a switch
or if
to loop through the array and then add each option manually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With