define multiple results all at the same time in php - php

I have $config variable that have arrays inside it. In smarty I assign the variable like this:
$smarty->assign('config', $config);
when I call it, I used this : {$config.wateverarrayyouwant}
now I want to do the same thing with php. I want to define them in the same manner. How can I define all the arrays in $config in just one line?
I only know how to define a variable one at a time by using this :
define('wateverarrayyouwant', $config['wateverarrayyouwant']);
I tried changing wateverarrayyouwant to a variable because it can be any array :
define('$wateverarrayyouwant', $config[$wateverarrayyouwant]);
but the code above does not work. what is a good way to achieve what I want?

If you want to create a define for each key value pair in the array you can use:
<?php
foreach($config as $key => $value) {
define($key, $value);
}
I will note however that you cannot define array values, all define's must be scalar:
The value of the constant; only scalar and null values are allowed. Scalar values are integer, float, string or boolean values.
If you check the OP's answer for further explanation of what he's trying to achieve, it can be done with:
<?php
foreach($config as $key => $value){
$$key = $value;
}
?>

This question cannot be done. because I am trying to define a variable as a constant. I was just thinking about how can I reduce the letters for variables and never though that I better leave them alone. Logically, why do somebody need to change $config[$wateverarrayyouwant] to wateverarrayyouwant. I was only thinking about maintaining a neat code. but now I am thinking about it.. it is better to leave it as it is : $config[$wateverarrayyouwant]
This can be done with:
foreach($config as $key => $value){
$$key = $value;
}

You may not even want to use define here. define is used to create constants not plain variables and that carries with it certain connotations:
they are immutable for the life of the script
they must be scalar
If you just want an array variable then define it like normal with:
$whatever = array(
'key1' => 'value1'
);

Related

php numeric Variable Name

I want to append some $variables automaticly and set their names numeric
I have a script look like this:
<?php
$i=0;
while($i<=100){
$variable_[$i]=$i;
$i++;
#with "[$i]" I mean their name will be $variable_1 , $variable_2, $variable_3 ...
#they will be automatic increased variables non manual!
}
?>
This is called variable variables.
You can set a variable variable by defining its name inside a variable, such as:
$name = 'variable_' . $i;
and then assign a value to it by doing:
$$name = $i;
Note that variable variables can easily be misused. Make sure you completely understand the repercussions of this feature on your code and the risk of having bugs, and ensure this is the only solution you have, i.e. you can't use an array ($variables[$i] = $i;) instead.
Its better to use Array with key=> value pair. You can build this array dynamically and then loop through it by using foreach.

PHP variable variable name containing index

$arr[0]=123;
$a="arr[0]";
echo $$a;
gives me error
Notice: Undefined variable: arr[0]
on the last line.
What should I do to make it work?
EDIT:
Above is the simplification of what I want to do. If someone wants to know why I want to do this, then here's the explanation:
This is something like what I want to do:
if(condition){
$a=$arr1[0][0];
$b=$arr1[0][1];
$c=$arr1[0][2];
}
else{
$a=$arr2[0];
$b=$arr2[1];
$c=$arr2[2];
}
I can compact it like this:
if(condition)
$arr=$arr1[0];
else
$arr=$arr2;
$a=$arr[0];
$a=$arr[1];
$a=$arr[2];
But I wanted to try doing this using variable variable:
if(condition)
$arr="$arr1[0]";
else
$arr="$arr2";
$a={$$arr}[0];
$b={$$arr}[1];
$c={$$arr}[2];
Sure, we don't need variable variables as we can still code without them. I want to know, for learning PHP, why the code won't work.
Now that you said what you’re actually trying to accomplish: Your code doesn’t work because if you look at $arr1[0][0], only arr is the variable name; the [0] are special accessors for certain types like strings or arrays.
With variable variables you can only specify the name but not any accessor or other operation:
A variable variable takes the value of a variable and treats that as the name of a variable.
Your solution with the additional variable holding the array to access later on would be the best solution to your problem.
What you are trying to do just won't work - the code $arr[0] is referencing a variable called $arr, and then applying the array-access operator ([$key]) to get the element with key 0. There is no variable called $arr[0], so you cannot reference it with variable-variables any more than you could the expression $foo + 1 .
The real question is why you want to do this; variable variables are generally a sign of very messy code, and probably some poor choices of data structure. For instance, if you need to select one of a set of variables based on some input, you probably want a hash, and to look up an item using $hash[$item] or similar. If you need something more complex, a switch statement can often cover the cases you actually need.
If for some reason you really need to allow an arbitrary expression like $arr[0] as input and evaluate it at runtime, you could use eval(), but be very very careful of where the input is coming from, as this can be a very easy way of introducing security holes into your code.
FROM PHP DOC
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.
Use
echo ${$a}[0]; // 123
Edit : Based on your edit you can simply have
list($a, $b, $c) = (condition) ? $arr1[0] : $arr2;
Or
$array = (condition) ? $arr1[0] : $arr2;
$a = $array[0];
$b = $array[1];
$c = $array[2];
As pointed out you don't need variable variables. To get a PHP variable variable name containing index (a key) use array_keys() or array_search() or other array parsers. From php's site:
$array = array(0 => 'blue', 1 => 'red', 2 => 'green', 3 => 'red');
$key = array_search('green', $array); // $key = 2;
$key = array_search('red', $array); // $key = 1;
You could also use the following (using $var= instead of echo):
$arr[0]=123;
$arr[1]=456;
foreach ($arr as $key => $value) {
echo "arr[{$key}] = {$value} \r\n";
}
Which outputs:
arr[0] = 123
arr[1] = 456
But I don't see why you'd do that, since the whole point of the array is not doing that kind of stuff.

PHP: testing for existence of a cell in a multidimensional array

I have an array with numerous dimensions, and I want to test for the existence of a cell.
The below cascaded approach, will be for sure a safe way to do it:
if (array_key_exists($arr, 'dim1Key'))
if (array_key_exists($arr['dim1Key'], 'dim2Key'))
if (array_key_exists($arr['dim1Key']['dim2Key'], 'dim3Key'))
echo "cell exists";
But is there a simpler way?
I'll go into more details about this:
Can I perform this check in one single statement?
Do I have to use array_key_exist or can I use something like isset? When do I use each and why?
isset() is the cannonical method of testing, even for multidimensional arrays. Unless you need to know exactly which dimension is missing, then something like
isset($arr[1][2][3])
is perfectly acceptable, even if the [1] and [2] elements aren't there (3 can't exist unless 1 and 2 are there).
However, if you have
$arr['a'] = null;
then
isset($arr['a']); // false
array_key_exists('a', $arr); // true
comment followup:
Maybe this analogy will help. Think of a PHP variable (an actual variable, an array element, etc...) as a cardboard box:
isset() looks inside the box and figures out if the box's contents can be typecast to something that's "not null". It doesn't care if the box exists or not - it only cares about the box's contents. If the box doesn't exist, then it obviously can't contain anything.
array_key_exists() checks if the box itself exists or not. The contents of the box are irrelevant, it's checking for traces of cardboard.
I was having the same problem, except i needed it for some Drupal stuff. I also needed to check if objects contained items as well as arrays. Here's the code I made, its a recursive search that looks to see if objects contain the value as well as arrays. Thought someone might find it useful.
function recursiveIsset($variable, $checkArray, $i=0) {
$new_var = null;
if(is_array($variable) && array_key_exists($checkArray[$i], $variable))
$new_var = $variable[$checkArray[$i]];
else if(is_object($variable) && array_key_exists($checkArray[$i], $variable))
$new_var = $variable->$checkArray[$i];
if(!isset($new_var))
return false;
else if(count($checkArray) > $i + 1)
return recursiveIsset($new_var, $checkArray, $i+1);
else
return $new_var;
}
Use: For instance
recursiveIsset($variables, array('content', 'body', '#object', 'body', 'und'))
In my case in drupal this ment for me that the following variable existed
$variables['content']['body']['#object']->body['und']
due note that just because '#object' is called object does not mean that it is. My recursive search also would return true if this location existed
$variables->content->body['#object']->body['und']
For a fast one liner you can use has method from this array library:
Arr::has('dim1Key.dim2Key.dim3Key')
Big benefit is that you can use dot notation to specify array keys which makes things simpler and more elegant.
Also, this method will work as expected for null value because it internally uses array_key_exists.
If you want to check $arr['dim1Key']['dim2Key']['dim3Key'], to be safe you need to check if all arrays exist before dim3Key. Then you can use array_key_exists.
So yes, there is a simpler way using one single if statement like the following:
if (isset($arr['dim1Key']['dim2Key']) &&
array_key_exists('dim3Key', $arr['dim1Key']['dim2Key'])) ...
I prefer creating a helper function like the following:
function my_isset_multi( $arr,$keys ){
foreach( $keys as $key ){
if( !isset( $arr[$key] ) ){
return false;
}
$arr = $arr[$key];
}
return $arr;
}
Then in my code, I first check the array using the function above, and if it doesn't return false, it will return the array itself.
Imagine you have this kind of array:
$arr = array( 'sample-1' => 'value-1','sample-2' => 'value-2','sample-3' => 'value-3' );
You can write something like this:
$arr = my_isset_multi( $arr,array( 'sample-1','sample-2','sample-3' ) );
if( $arr ){
//You can use the variable $arr without problems
}
The function my_isset_multi will check for every level of the array, and if a key is not set, it will return false.

Can you get a variable name as a string in PHP? (And should you?)

Say you have several large arrays of variables (which generally are strings), and you want to change how they are displayed on certain pages – for example by concatenating each of them with $prefix and $suffix:
$arr = array($foo, $bar, $baz)
$foo_display = $prefix . $foo . $suffix
$bar_display = $prefix . $bar . $suffix
$baz_display = $prefix . $baz . $suffix
How would you avoid having to make all these assignments manually? I originally assumed there would be some function which would return a variable's name as a string (call it "varname()"), in which case the code might look like this:
foreach ($arr as &$value) {
${varname($value)."_display"} = $prefix . $value . $suffix
}
But I haven't been able to find such a function, and people in this similar thread seemed to think the entire concept was suspect.
PS: I'm new to programming, sorry if this is a dumb question :)
There are multiple problems with what you want to do. For example, the name of the variable is not accessible. The code $arr = array($foo, $bar, $baz) creates an array with the values of the $foo, etc. If you then changed the value of $foo, the value of $arr[0] is still the old value of $foo, so it's not even clear what it would mean to have access to the variables name.
Even if it were easy to do, I would consider it very poor practise, simply because you'd need to know by introspection what the correct variable names would be.
Of course, this is all easily solved if you had an associative array. For example:
$arr = array('Foo' => $foo, 'Bar' => $bar, 'Baz' => $baz)
This could easily be altered to produce what you want. For example:
$display = array();
foreach($arr as $key => $value)
$display[$key] = $prefix . $value . $suffix;
I would need a more detailed example of what you are trying to accomplish, but the direction I would give you is to look into how PHP does key/value pairs:
http://php.net/manual/en/language.types.array.php
This way you can access your arrays like this:
foreach ($valsArr as $key => $val) {
$displayX = $prefix.$superArr[$key.'_display'].$suffix;
}
This will have to be tailored to your specific structures/mappings. Going the route of trying to use variable names to do any sort of mappings is going to be tough.
Although one can derive the variable name from the $GLOBALS array, iterating over the variable-value pairs just doesn't make much sense when you can create your own custom associative array to track these variable-value pairs anyway. And if you had two or more instances of $value having the same content, how would you expect a program to trace the variable name thru introspection? It can soon be a big mess.
You should keep track of it in the code yourself.

Will this foreach copy the values in memory?

Example:
foreach ($veryFatArray as $key => $value) {
Will the foreach assign the value behind the $key by reference to $value, or will $value be a copy of what's stored in the array? And if yes, how could I get an reference only? The array values store pretty big amounts of data so copying them is not really good.
Don't try and second-guess the interpreter is the moral of the story here. $value is actually a copy but an efficient copy. PHP uses pass-by-value (for non-objects) but also uses copy-on-write. What this means is that if you write:
foreach ($bigitems as $bigitem) {
echo $bigitem; // uses original
$bigitem = 'foo'; // item copied and assigned 'foo'
echo $bigitem; // uses copy
}
Just declare your intent: that you want to use the array values. Let PHP sort it out after that. Basically only use references in the loop like this if you intend to change the array. Otherwise you're sending the wrong message to someone else who reads your code.
Section 1 of Copy-on-Write in the PHP Language should tell you everything you ever wanted to know about PHP copy-on-write.
$value will be a copy, but (please someone correct me if I'm wrong here), PHP is actually very smart about pass-by-value type things. It will actually do a pass-by-reference and only copy if you modify the variable. For example:
function foo ($bar) {
echo $bar['x'];
// internally, $bar is a reference to $baz. (virtually) no extra memory used
$bar['y'] = 'Y';
// only now has the array been copied in memory
}
$baz = array('x' => '1', 'y' => '2');
foo($baz);
In your foreach, if you want to modify the original array, you could do this:
// PHP 4
foreach (array_keys($veryFatArray) as $key) {
$value =& $veryFatArray[$key];
// ...
}
// PHP 5
foreach ($veryFatArray as $key => &$value) { }
If you are only reading from $value and not writing to it, then it shouldn't be a problem.

Categories