I was wondering whether something like this is possible:
$var1 = 1; $var2 = 2;
function varsToArray($param1, $param2...);
and it returns array like this
array([var1] => 1, [var2] => 2).
Simply saying, I'd like arrays keys to be same as variable names. The problem is I don't know how to get variable name as string to put it as key(if possible of course...).
You want to use the compact function methinks.
The built-in PHP function compact() does this.
BTW: I'm going to go ahead and assume that instead of:
function $varsToArray($var1, $var2...);
you actually meant:
function varsToArray($var1, $var2...);
Notice the dollar sign has been removed.
Related
I'm trying to extract values from an array, and pass them to a function where they'll be used. I've used echo inside the function for this example.
I'm using extract to get all the values.
Thing is, this wont work. Do you see how this can be done?
<?php
$my_array = array("a" => "Prince", "b" => "Funky"); // around 10 more
$g = extract($my_array);
foo($g);
function foo($g) {
echo 'My name is '.$a.', and I am '.$b;
}
?>
Functions in PHP have a different scope, so the variables $a, $b etc. aren't available inside your function. Trying to use them inside the function would result in Undefined variable notices (if you enable error reporting, that is).
Right now, you're storing the return value of extract() (which is the total number of variables parsed) into your function. You want the values instead, so change your function like so:
function foo($array) {
extract($array);
echo 'My name is '.$a.', and I am '.$b;
}
Note that I've moved the extract() call inside the function. This way, you wouldn't pollute the global scope with random variables (which may have undesired results and will make your debugging hard for no reason).
Now you can call your function, like so:
foo($my_array);
Output:
My name is Prince, and I am Funky
Demo
It's better to avoid extract() altogether, though. See: What is so wrong with extract()?
You can pass your array in your function as you do with any other variable
$my_array = array("a" => "Prince", "b" => "Funky"); // around 10 more
foo($my_array);
function foo($arrayData)
{
echo 'My name is '.$arrayData['a'].', and I am '.$arrayData['b'];
}
I have a multidimensional array produced by json_decode(). The json is dynamically generated, that means some keys will be present randomly.
I would like to avoid Undefined index: notice, so i encapsulated the calls to the array in a function like this:
function exists($value) {
if (isset($value)) {
return $value;
}
}
I then call data:
$something = exists($json_array['foo']['bar']['baz']);
But i still get the Undefined index: baz notice. Any suggestions?
It seems you are new to PHP, so I'll give a bit lengthier answer than normal.
$something = exists($json_array['foo']['bar']['baz']);
This is equivalent to what you wrote:
$baz = $json_array['foo']['bar']['baz'];
$something = exists($baz);
As you may have noticed, this means that $json_array['foo']['bar']['baz'] is evaluated before it's passed to exists(). This is where the undefined index is coming from.
The correct idiom would be more like this:
$something = NULL;
if (isset($json_array['foo']['bar']['baz'])) {
$something = $json_array['foo']['bar']['baz'];
}
The following is also identical to the above lines:
$something = isset($json_array['foo']['bar']['baz'])
? $json_array['foo']['bar']['baz']
: NULL;
You would have to chain the exists calls one by one, because you are trying to dereference the array before you send it to the exists function.
See this question for more info: Check if a "run-time" multidimensional array key exists
$json_array['foo']['bar']['baz'] fails when you pass it as an argument, before it's passed to isset(). That is your problem.
$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.
What does this line mean?
if ( ${fun("str1")} (fun("str2"), ${fun("str3")}) )
Evaluate function returning_value_for_str1_of_fun()_name with the parameters return value for str2 and variable with name return_value_for_str3 ?
This tests the return value of the function, whose name is the value in the variable named fun("str1"), and given the arguments fun("str2") and the value of the variable named fun("str3").
Example:
If fun("str1") equals "x", fun("str2") equals 34, and fun("str3") equals "y", then the statement would look like:
if ( $x (34, $y) )
fun("str1") returns string that should be name of variable and the value of this variable is anonymous function (that probably is not void and returns boolean) that gets two arguments first is return value fun("str2") and the second is the value of the variable with the name that matches string returned by fun("str3").
Wow. That's convoluted code. Let's examine it bit by bit:
Let's start with this:
fun("str1")
In fact, this is simply a function call to a function named fun(), passing in a string value as a parameter.
This function call is repeated three times in your code, with different strings as the arguments. The function fun() itself is not supplied in your example code, so I can't tell what it does, but given the context I assume it returns a string.
Which leads us onto the next bit we can examine:
${fun("str1")}
The ${...} syntax in PHP takes the contents of the braces and references a variable of that name.
So, for example, ${"myvar"} is the same as saying $myvar. This is called a dynamic variable name. While it does have its uses, it is a very easy way to write bad code, that is difficult to read, understand or maintain. Your example definitely falls into this category.
However, now that we understand the syntax, it's easy to see that it is taking the string output of the fun() function call, and turning it into a variable name.
Expanding further, we can rewrite the code as follows to make it clearer:
$var1 = fun("str1");
$var2 = fun("str2");
$var3 = fun("str3");
if ( $$var1 ($var2, $$var3) )
Here, $$var1 is being used as a function name, called with $var2 and $$var3 as parameters.
So in $var1, we have a function call returning a string that is being referenced as a variable name, which is being called as a function.
We still don't know what fun() function returns, or whether the variable names that are generated by its return are valid, but we can make some assumptions, as $var1 and $var2 would need to be populated with valid function names in order for your line of code to work at all.
We now have an understanding of the whole line of code, but still not a clear view of what it's trying to acheive (beyond being excessively 'clever' and obtuse).
This is very very poorly written code. It is deliberately obscure, and inefficient (ie it will run slowly).
Some work around:
$func = 'fun';
$str3 = 'str3';
echo ${fun("str1")} (fun("str2"), ${fun("str3")}); // will output 'str2'
function fun($param1, $param2 = ''){
if($param1 == 'str2' || $param1 == 'str3')
return $param1;
elseif($param1 == 'str1')
return 'func';
else
echo ' you are done';
}
Evaluates as follows:
fun("str1") -> 'func'
${fun("str1")} -> $func -> fun
fun("str2") -> 'str2'
fun("str3") -> 'str3'
${fun("str3")} -> $str3
${fun("str1")} (fun("str2"), ${fun("str3")})
=> $func ("str2", $str3)
=> fun("str2", "str3")
=> "str2"
This seem so simple, and yet I can't find a solution anywhere.
What I want to do is add the contents (r-value) of a variable to an associative array instead of a reference to the variable.
For example, I want this:
$myStr1 = "sometext";
$myStr2 = "someothertext";
$myArray = array(
"key1"=>$myStr1,
"key2"=>$myStr2
);
echo($myArray["key1"]);
To produce this:
"sometext"
Instead of this:
"1" // why??
Any help would be appreciated.
EDIT:
The above works; my bad. Here's the real problem - my $myStr1 variable isn't just assiged a string literal like in the above; it's created using the following syntax:
$myStr1 = "sometext" + anObject->intProperty + "moretext";
Basically I use the + to concatenate various types into a string. Maybe + isn't doing what I think it's doing?
EDIT:
It was definitely the + operator. I casted all non-strings to strings and used . to concatenate instead.
You've got it correct the first time. Try this:
$myStr1 = "sometext";
$myStr2 = "someothertext";
$myArray = array(
"key1"=>$myStr1,
"key2"=>$myStr2
);
unset($myStr1);
echo($myArray["key1"]);
Even though we unset() the $myStr1 variable, it still echoed sometext.
It should be noted that while it is possible to set $myStr1 by reference, it's not the default.
Try your code and its result is:
sometext