Dumping many variables in PHP - php

I assure this is a very common situation when you have to test variables (and they are many!), just like this example (I only named vars like this for less-effort-writing sake):
$variable0='red';
$variable1='blue';
$variable2='green';
$variable3='pink';
$variable4='purple';
$variable5='hellow';
$variable6='foo';
$variable7='bar';
$variable8='hi';
$variable9='bye';
echo
'$variable0='.$variable0.'<br>
$variable1='.$variable1.'<br>
$variable2='.$variable2.'<br>
$variable3='.$variable3.'<br>
$variable4='.$variable4.'<br>
$variable5='.$variable5.'<br>
$variable6='.$variable6.'<br>
$variable7='.$variable7.'<br>
$variable8='.$variable8.'<br>
$variable9='.$variable9;
My question is: is there a better way to make this echoing / dumping / printing easier?
Of course, there are other ways of doing the very same presidiary work:
$x=
'$variable0='."$variable0\n".
'$variable1='."$variable1\n".
'$variable2='."$variable2\n".
'$variable3='."$variable3\n".
'$variable4='."$variable4\n".
'$variable5='."$variable5\n".
'$variable6='."$variable6\n".
'$variable7='."$variable7\n".
'$variable8='."$variable8\n".
'$variable9='."$variable9"
echo nl2br($x);
Or:
$x=<<<HEREDOC
\$variable1=$variable1
\$variable2=$variable2
\$variable3=$variable3
\$variable4=$variable4
\$variable5=$variable5
\$variable6=$variable6
\$variable7=$variable7
\$variable8=$variable8
\$variable9=$variable9;
HEREDOC;
echo nl2br($x);
But maybe PHP has a function to make this easier?
By the way, all 3 solutions above echoes the very same:
$variable1=blue<br>
$variable2=green<br>
$variable3=pink<br>
$variable4=purple<br>
$variable5=hellow<br>
$variable6=foo<br>
$variable7=bar<br>
$variable8=hi<br>
$variable9=bye;

Introducing compact:
var_dump(compact('foo', 'bar', 'baz'));
Note though that I explicitly used three very different variables: $foo, $bar and $baz.
If you actually do literally have $foo1, $foo2 etc, you're really really looking to use an array instead. Dumping that would be trivial too:
$foo = array();
$foo[0] = 'bar';
$foo[1] = 'baz';
var_dump($foo);
In general, if you have too many variables floating around, your scope is probably too big and you should refactor everything into a number of smaller functions, or your algorithm is more complex than it needs to be, or you should be using arrays or other data structures instead.

get_defined_vars() would be able to do so. Might be overkill (all accessable vars will be shown):
print_r( get_defined_vars() );
Return Values: A multidimensional array with all the defined variables*.
*In a function it will only show the local $vars, and those defined as global.
Note: This does exactly what you're looking for, but the array methods mentioned in other answers would be a better fit logical-wise, see below:
A better way for you to set the values is with an array, this way you 'group' multiple values together:
$color[] = 'red'; // will automatically start with key=0
$color[] = 'blue'; // key=1
$color[] = 'green';// key=2 etc
print_r( $color );
echo $color[1]; // Blue, same as your echo $variable1;

You can declare your variables as keys from an array instead
$myarray=Array();
$myarray['variable0']='red';
$myarray['variable1']='blue';
$myarray['variable2']='green';
$myarray['variable3']='pink';
$myarray['variable4']='purple';
$myarray['variable5']='hellow';
$myarray['variable6']='foo';
$myarray['variable7']='bar';
$myarray['variable8']='hi';
$myarray['variable9']='bye';
and print them all with
echo '<pre>';
print_r($myarray);
echo '</pre>';
then, in case you still need to use them as separate variables, doing
extract($myarray)
will create $variable0 to $variable9 in the global context.

If you know the upper and lower bounds and all the variables have a similar name you could do the following:
for ($i = 0; $i < $end; ++$i) { echo ${'value_name'. $i}; }

Try refactor your code and use arrays
Then you can do print_r or var_dump

This should give you the output your looking for:
function get_var_name($var) {
foreach($GLOBALS as $var_name => $value) {
if ($value === $var) {
return $var_name;
}
}
return "Variable name not found";
}
function miracle_var_dump($valuesToDump) {
//For each variable in the $valuesToDump array, print the name and value
for($i = 0; $i < count($valuesToDump); $i++) {
echo(get_var_name($valuesToDump[i]) . "=" . $valuesToDump[i] . "<br/>");
}
}
//Making a call to dump the variables
miracle_var_dump(array($variable0,$variable1,$variable2,$variable3,$variable4,$variable5,$variable6,$variable7,$variable8,$variable9))
Function get_var_name gets the variable name given the variable (taken from one of Jeremey Rutins awsners).

//let your variables like this
$variable0='red';
$variable1='blue';
$variable2='green';
//an array to keep all the variable names
$var_names=array();
$var_names[]='$variable0';
$var_names[]='$variable1';
$var_names[]='$variable2';
//etc...
print_var_name($var_names);
function print_var_name($var_names) {
//loop through the array and dump them if they are in $GLOBALS
foreach($GLOBALS as $var_name => $value) {
if (in_array('$'.$var_name,$var_names)) {
echo $var_name;
var_dump($value);
}
}

Related

How do you print a variable in PHP that's either one element of an array, or the whole variable if it's not an array

Say I have $exampleVariable, which I want to print. $exampleVariable may be an array, in which case I have this set up to get the right array element, which I can then print with print $exampleVariable[$i].
if ($_GET) {
$i = array_search($_GET["exampleQueryString"], $exampleVariable);
} elseif (is_array($exampleVariable)) {
$i = 0;
} else {
$i = "";
}
My problem is that last else, if $exampleVariable is NOT an array, because then I get print $exampleVariable[] which doesn't work. So is there something I can put as $i to print the whole variable?
Alternatively, I considered including the brackets in $i, so I'd have for example $i = [0];, but in that case I don't know how I'd print it. $exampleVariable$i certainly won't work.
I have a good number of variables besides $exampleVariable I'll need to print, all with the same $i or lack thereof, so I'd like to not have to do anything longwinded to set each of them up individually.
This sounds way more complicated than I feel like it should, so hopefully it makes sense!
You can always do a nifty thing that is called type casting. That means, that you can always make a variable an array even if it is not, by prepending its name by (array):
$exampleVariable = (array)$exampleVariable;
So you don't need three if branches at all:
if ($_GET) { 
$i = array_search($_GET["exampleQueryString"], $exampleVariable);
} else {
$i = 0;
$exampleVariable = (array)$exampleVariable;
}
You could apply the (array) cast, which will have no effect if the target is already an array:
$i = array_search($_GET["exampleQueryString"], (array)$exampleVariable);

How to change the order of function calls based on the value of a variable

I am developing a WordPress plugin and I have the following situation:
$functions1 = 7; //users can select this value and this can be something between 1-7
$functions2 = 5; //these values are positions to be precise
$functions3 = 6; //no two variables can have same value as each position is unique
$functions4 = 3; //we can also make $functions1-7 an array to avoid making 7 variables
$functions5 = 4;
$functions6 = 2;
$functions7 = 1;
I need to change the order of executions these function calls based on the value of the relative variables mentioned above:
function1();
function2();
function3();
function4();
function5();
function6();
function7();
All these functions return some HTML like:
function1(){ return "<div>Hello World from function1</div>" }
.
.
function7(){return "<div>Hello World from function7</div>"}
In the current sequential form irrespective of the values of the $functions1-7 variables above, the functions will execute in the order in which they are called.
What is the best approach to change the order of the function calls based on the values of $functions1-7 variables like if $functions4 = 7 then function4() should be the last function call to be executed.
Please suggest an optimal approach to the solution, thanks!
Make it 1 function that will return different results depending on the value of the variable:
function testFunction($var) {
if ($var == 1)
return "<div>Hello World from function1</div>";
if ($var == 7)
return "<div>Hello World from function7</div>";
...
}
then you can run it like this:
testFunction($functions1);
EDIT: First I didn't understand your question completely, so let me extend my answer.
In order to run the function in the required order, best is probably to use an array:
$array = array($functions1, $functions2, $functions3, $functions4, $functions5, $functions6, $functions7);
then do the same as above but put it in a loop:
for ($i = 0; $i<count($array); $i++)
echo testFunction($array[$i]);
Here is a demo: http://3v4l.org/mgOKh
it can be done using associative array and foreach for example
function Func3(){
echo '3';
}
function Func1(){
echo '1';
}
$a = [3=>'Func3',1=>'Func1'];
ksort($a);
foreach($a as $k=>$v){
$fname = $a[$k];
$fname();
}
not tested.
resources:
php.net/manual/en/functions.variable-functions.php, php.net/manual/en/function.ksort.php

Is there a way to pass entire scope to a function

Before going into the details of this question, I'd like to point out that I have never seen this done before, and would be rather curious to see if it can actually be done, and if so, how to go about doing it.
I'm currently sitting on a template loader, and to write it, I have chosen to slightly adapt the HAML file format and extend it with a couple of logic operators - loops, mostly. To do so efficiently, I'd need to pass a list of parameters to the template parser...and I'd prefer to avoid this if possible. While brainstorming for alternatives, the idea came around that maybe, just maybe, it would be possible to reference the scope in which the function was called.
Currently, I'm calling the template parser for a file as follows. Suppose test() is a route.
function test() {
$q = $UserModel->tether($userID)->fetchPermissions();
Util::Templating()->parse("file.haml");
}
What I'm trying to avoid is being able to access $q without passing a massively long array as second parameter. My original thought was that there might be a way for parse() to inherit the scope in which it was originally called (here, inside test) rather than having its own. Is there a way to manage this, and if so, how efficient is it?
Includes the superglobals as well:
$a = 'Hello World';
$b = range('A','Z');
$scopeVars = get_defined_vars();
var_dump($scopeVars);
test($scopeVars);
function test($scopeVars) {
extract($scopeVars);
echo '$a = '; var_dump($a);
echo '$b = '; var_dump($b);
}
EDIT
Just as an experiment, to eliminate the superglobals:
$a = 'Hello World';
$b = range('A','Z');
$scopeVars = get_user_defined_vars(get_defined_vars());
test($scopeVars);
function test($scopeVars) {
extract($scopeVars);
echo '$a = '; var_dump($a);
echo '$b = '; var_dump($b);
}
function get_user_defined_vars($vars) {
return array_diff_key(
$vars,
array_flip(
array('_SERVER','_GET', '_POST', '_REQUEST', '_FILES', '_COOKIE', '_ENV')
)
);
}
But removing the superglobals does seem to make it a bit slower
So i think creating a view object setting it properties and than passing it could work. Or instead of object work with array directly. e.g:
function test() {
$params = array();
$params['var_1'] = 'qwe1';
$params['var_2'] = 'qwe2';
$params['var_3'] = 'qwe3';
$params['var_4'] = 'qwe4';
$params['q'] = $UserModel->tether($userID)->fetchPermissions();
Util::Templating()->parse("file.haml", $params);
}

Efficiency of using foreach loops to clear a PHP array's values

Which is more efficient for clearing all values in an array? The first one would require me to use that function each time in the loop of the second example.
foreach ($array as $i => $value) {
unset($array[$i]);
}
Or this
foreach($blah_blah as $blah) {
$foo = array();
//do something
$foo = null;
}
I don't want to use unset() because that deletes the variable.
Like Zack said in the comments below you are able to simply re-instantiate it using
$foo = array(); // $foo is still here
If you want something more powerful use unset since it also will clear $foo from the symbol table, if you need the array later on just instantiate it again.
unset($foo); // $foo is gone
$foo = array(); // $foo is here again
If we are talking about very large tables I'd probably recommend
$foo = null;
unset($foo);
since that also would clear the memory a bit better. That behavior (GC) is however not very constant and may change over PHP versions. Bear in mind that re-instantiating a structure is not the same as emptying it.
If you just want to reset a variable to an empty array, you can simply reinitialize it:
$foo = array();
Note that this will maintain any references to it:
$foo = array(1,2,3);
$bar = &$foo;
// ...
$foo = array(); // clear array
var_dump($bar); // array(0) { } -- bar was cleared too!
If you want to break any references to it, unset it first:
$foo = array(1,2,3);
$bar = &$foo;
// ...
unset($foo); // break references
$foo = array(); // re-initialize to empty array
var_dump($bar); // array(3) { 1, 2, 3 } -- $bar is unchanged
Unsetting the variable is a nice way, unless you need the reference of the original array!
To make clear what I mean:
If you have a function wich uses the reference of the array, for example a sorting function like
function special_sort_my_array(&$array)
{
$temporary_list = create_assoziative_special_list_out_of_array($array);
sort_my_list($temporary_list);
unset($array);
foreach($temporary_list as $k => $v)
{
$array[$k] = $v;
}
}
it is not working! Be careful here, unset deletes the reference, so the variable $array is created again and filled correctly, but the values are not accessable from outside the function.
So if you have references, you need to use $array = array() instead of unset, even if it is less clean and understandable.
I'd say the first, if the array is associative. If not, use a for loop:
for ($i = 0; $i < count($array); $i++) { unset($array[$i]); }
Although if possible, using
$array = array();
To reset the array to an empty array is preferable.
Isn't unset() good enough?
unset($array);
How about $array_name = array(); ?
Use array_splice to empty an array and retain the reference:
array_splice($myArray, 0);
i have used unset() to clear the array but i have come to realize that unset() will render the array null hence the need to re-declare the array like for example
<?php
$arr = array();
array_push($arr , "foo");
unset($arr); // this will set the array to null hence you need the line below or redeclaring it.
$arr = array();
// do what ever you want here
?>
Maybe simple, economic way (less signs to use)...
$array = [];
We can read in php manual :
As of PHP 5.4 you can also use the short array syntax, which replaces array() with [].
I see this questions is realla old, but for that problem I wrote a recursive function to unset all values in an array. Recursive because its possible that values from the given array are also an array. So that works for me:
function empty_array(& $complete_array) {
foreach($complete_array as $ckey => $cvalue)
{
if (!is_array($cvalue)) {
$complete_array[$ckey] = "";
} else {
empty_array( $complete_array[$ckey]);
}
}
return $complete_array;
}
So with that i get the array with all keys and sub-arrays, but empty values.
The unset function is useful when the garbage collector is doing its rounds while not having a lunch break;
however unset function simply destroys the variable reference to the data, the data still exists in memory and PHP sees the memory as in use despite no longer having a pointer to it.
Solution:
Assign null to your variables to clear the data, at least until the garbage collector gets a hold of it.
$var = null;
and then unset it in similar way!
unset($var);
The question is not really answered by the posts. Keeping the keys and clearing the values is the focus of the question.
foreach($resultMasterCleaned['header'] as $ekey => $eval) {
$resultMasterCleaned[$key][$eval] = "";
}
As in the case of a two dimensional array holding CSV values and to blank out a particular row. Looping through seems the only way.
[] is nearly 30% faster then as array()
similar as pushing new element to array
$array[] = $newElement then array_push($array, $newElement)
(keep in mind array_push is slower only for single or 2 new elements)
Reason is we skip overhead function to call those
PHP array vs [ ] in method and variable declaration

"Large multiple variable echo's" way to make simpler?

Say I am echoing a large amount of variables in PHP and I wont to make it simple how do i do this? Currently my code is as follows but it is very tedious work to write out all the different variable names.
echo $variable1;
echo $variable2;
echo $variable3;
echo $variable4;
echo $variable5;
You will notice the variable name is the same except for an incrementing number at the end. How would I write a script that prints echo $variable; so many times and adds an incrementing number at the end to save me writing out multiple variable names and just paste one script multiple times.?
Thanks, Stanni
You could use Variable variables:
for($x = 1; $x <= 5; $x++) {
print ${"variable".$x};
}
However, whatever it is you're doing there is almost certainly a better way: probably using Arrays.
I second Paolo Bergantino. If you can use an array that would be better. If you don't how to do that, here you go:
Instead of making variables like:
$var1='foo';
$var2='bar';
$var3='awesome';
... etc... you can make a singe variable called an array like this:
$my_array = array('foo','bar','awesome');
Just so you know, in an array, the first element is the 0th element (not the 1st). So, in order to echo out 'foo' and 'bar' you could do:
echo $my_array[0]; // echoes 'foo'
echo $my_array[1]; // echoes 'bar'
But, the real benefits of putting value in an array instead of a bunch of variables is that you can loop over the array like this:
foreach($my_array as $item) {
echo $item;
}
And that's it. So, no matter how many items you have in your array it will only take those three lines to print them out. Good luck you with learning PHP!
Use dynamic variable names:
for($i=1; $i < 6; $i++) echo ${'variable'.$i}

Categories