I have a variable $var that can only be set to, let's say, a or b. I have two global arrays, e.g. $aNames and $bNames. Finally there's also a variable $number. To bring everything together, I'd like to combine the values to get an element from the array.
Example:
$var = 'a';
$number = 2;
$el = "$$var"."Names[".$number."]";
$el == $aNames[2] // true
But I'm not sure how to write that first $el line without it being interpreted as a string.
This would do:
$el = ${$var.'Names'}[$number];
Example:
<?php
$aNames[2] = 10;
$var = 'a';
$number = 2;
$el = ${$var.'Names'}[$number];
echo $el; //10
and now
$el == $aNames[2]
will evaluate to true
Related
Consider this code:
$var = 'test';
$_POST[$test]; // equals $_POST['test']
How can I access with the same method this variable:
$_POST['test'][0];
$var = 'test[0]'; clearly doesn't work.
EDIT
Let me give a bit more information. I've got a class that builds a form.
An element is added like this:
//$form->set_element(type, name, defaultValue);
$form->set_element('text', 'tools', 'defaultValue');
This results into :
<input type="text" name="tools" value="defaultValue" />
In my class I set the value: if the form is posted, use that value, if not, use the default:
private function set_value( $name, $value='' ) {
if( $_SERVER['REQUEST_METHOD'] == 'POST' )
return $_POST[$name];
else
return $value;
}
When I want to add multiple "tools", I would like to use:
$form->set_element('text', 'tools[0]', 'defaultValue');
$form->set_element('text', 'tools[1]', 'defaultValue');
$form->set_element('text', 'tools[2]', 'defaultValue');
But in the set_value function
that gives $_POST['tools[0]'] instead of $_POST['tools'][0]
Use any number of variables in [] to access what you need:
$test = 'test';
$index = 0;
var_dump($_POST[$test][$index]);
$test = 'test';
$index = 0;
$subkey = 'key'
var_dump($_POST[$test][$index][$subkey]);
And so on.
There's no special function to achieve what you want, so you should write something, for example:
$key = 'test[0]';
$base = strstr($key, '[', true); // returns `test`
$ob_pos = strpos($key, '[');
$cb_pos = strpos($key, ']');
$index = substr($key, $ob_pos + 1, $cb_pos - $ob_pos - 1);
var_dump($arr[$base][$index]);
Edit by LinkinTED
$key = 'test[0]';
$base = $n = substr($name, 0, strpos($key, '[') );
preg_match_all('/\[([^\]]*)\]/', $key, $parts);
var_dump($arr[$base][$parts[1][0]]);
See how when you did $_POST['test'][0]; you just added [0] to the end? As a separate reference.
You have to do that.
$_POST[$test][0];
If you need both parts in variables then you need to use multiple variables, or an array.
$var = Array( "test", "0" );
$_POST[$test[0]][$test[1]];
Each dimension of an array is called by specifying the key or index together with the array variable.
You can reference a 3 dimensional array's element by mentioning the 3 indexes of the array.
$value = $array['index']['index']['index'];
Like,
$billno = $array['customers']['history']['billno'];
You can also use variables which has the index values that can be used while specifying the array index.
$var1 = 'customers';
$var2 = 'history';
$var3 = 'billno';
$billno = $array[$var1][$var2][$var3];
Is it possible to create a variable variable pointing to an array or to nested objects? The php docs specifically say you cannot point to SuperGlobals but its unclear (to me at least) if this applies to arrays in general.
Here is my try at the array var var.
// Array Example
$arrayTest = array('value0', 'value1');
${arrayVarTest} = 'arrayTest[1]';
// This returns the correct 'value1'
echo $arrayTest[1];
// This returns null
echo ${$arrayVarTest};
Here is some simple code to show what I mean by object var var.
${OBJVarVar} = 'classObj->obj';
// This should return the values of $classObj->obj but it will return null
var_dump(${$OBJVarVar});
Am I missing something obvious here?
Array element approach:
Extract array name from the string and store it in $arrayName.
Extract array index from the string and store it in $arrayIndex.
Parse them correctly instead of as a whole.
The code:
$arrayTest = array('value0', 'value1');
$variableArrayElement = 'arrayTest[1]';
$arrayName = substr($variableArrayElement,0,strpos($variableArrayElement,'['));
$arrayIndex = preg_replace('/[^\d\s]/', '',$variableArrayElement);
// This returns the correct 'value1'
echo ${$arrayName}[$arrayIndex];
Object properties approach:
Explode the string containing the class and property you want to access by its delimiter (->).
Assign those two variables to $class and $property.
Parse them separately instead of as a whole on var_dump()
The code:
$variableObjectProperty = "classObj->obj";
list($class,$property) = explode("->",$variableObjectProperty);
// This now return the values of $classObj->obj
var_dump(${$class}->{$property});
It works!
Use = & to assign by reference:
$arrayTest = array('value0', 'value1');
$arrayVarTest = &$arrayTest[1];
$arrayTest[1] = 'newvalue1'; // to test if it's really passed by reference
print $arrayVarTest;
In echo $arrayTest[1]; the vars name is $arrayTest with an array index of 1, and not $arrayTest[1]. The brackets are PHP "keywords". Same with the method notation and the -> operator. So you'll need to split up.
// bla[1]
$arr = 'bla';
$idx = 1;
echo $arr[$idx];
// foo->bar
$obj = 'foo';
$method = 'bar';
echo $obj->$method;
What you want to do sounds more like evaluating PHP code (eval()). But remember: eval is evil. ;-)
Nope you can't do that. You can only do that with variable, object and function names.
Example:
$objvar = 'classObj';
var_dump(${$OBJVarVar}->var);
Alternatives can be via eval() or by doing pre-processing.
$arrayTest = array('value0', 'value1');
$arrayVarTest = 'arrayTest[1]';
echo eval('return $'.$arrayVarTest.';');
eval('echo $'.$arrayVarTest.';');
That is if you're very sure of what's going to be the input.
By pre-processing:
function varvar($str){
if(strpos($str,'->') !== false){
$parts = explode('->',$str);
global ${$parts[0]};
return $parts[0]->$parts[1];
}elseif(strpos($str,'[') !== false && strpos($str,']') !== false){
$parts = explode('[',$str);
global ${$parts[0]};
$parts[1] = substr($parts[1],0,strlen($parts[1])-1);
return ${$parts[0]}[$parts[1]];
}else{
return false;
}
}
$arrayTest = array('value0', 'value1');
$test = 'arrayTest[1]';
echo varvar($test);
there is a dynamic approach for to many nested levels:
$attrs = ['level1', 'levelt', 'level3',...];
$finalAttr = $myObject;
foreach ($attrs as $attr) {
$finalAttr = $finalAttr->$attr;
}
return $finalAttr;
Is there a way to define a php variable to be one or the other just like you would do var x = (y||z) in javascript?
Get the size of the screen, current web page and browser window.
var width = window.innerWidth
|| document.documentElement.clientWidth
|| document.body.clientWidth;
var height = window.innerHeight
|| document.documentElement.clientHeight
|| document.body.clientHeight;
i'm sending a post variable and i want to store it for a later use in a session. What i want to accomplish is to set $x to the value of $_POST['x'], if any exist, then check and use $_SESSION['x'] if it exist and leave $x undefined if neither of them are set;
$x = ($_POST['x'] || $_SESSION['x');
According to http://php.net/manual/en/language.operators.logical.php
$a = 0 || 'avacado'; print "A: $a\n";
will print:
A: 1
in PHP -- as opposed to printing "A: avacado" as it would in a
language like Perl or JavaScript.
This means you can't use the '||' operator to set a default value:
$a = $fruit || 'apple';
instead, you have to use the '?:' operator:
$a = ($fruit ? $fruit : 'apple');
so i had to go with an extra if encapsulating the ?: operation like so:
if($_POST['x'] || $_SESSION['x']){
$x = ($_POST['x']?$_POST['x']:$_SESSION['x']);
}
or the equivalent also working:
if($_POST['x']){
$x=$_POST['x'];
}elseif($_SESSION['x']){
$x=$_SESSION['x'];
}
I didn't test theses but i presume they would work as well:
$x = ($_POST['x']?$_POST['x']:
($_SESSION['x']?$_SESSION['x']:null)
);
for more variables i would go for a function (not tested):
function mvar(){
foreach(func_get_args() as $v){
if(isset($v)){
return $v;
}
} return false;
}
$x=mvar($_POST['x'],$_SESSION['x']);
Any simple way to achieve the same in php?
EDIT for clarification: in the case we want to use many variables $x=($a||$b||$c||$d);
A simpler approach is to create a function that can accept variables.
public function getFirstValid(&...$params){
foreach($params as $param){
if (isset($param)){
return $param;
}
}
return null;
}
and then to initialize a variable i would do...
var $x = getFirstValid($_POST["x"],$_SESSION["y"],$_POST["z");
the result will be that the var x will be assign the first variable that is set or is set to null if none of the variables pass are set.
explanation:
function getFirstValid accepts a variable number of variable pointers(&...) and loops through each checking if it is set, the first variable encountered that is set will be returned.
Yes you need to use simple ternary operator which you have used within your example along with some other functions of PHP like as of isset or empty functions of PHP. So your variable $x will be assigned values respectively
Example
$x = (!empty($_POST['x'])) ? $_POST['x'] : (!empty($_SESSION['x'])) ? $_SESSION['x'] : NULL;
So the above function depicts that if your $_POST['x'] is set than the value of
$x = $_POST['x'];
else it'll check for the next value of $_SESSION if its set then the value of $x will be
$x = $_SESSION['x'];
else the final value'll be
$x = null;// you can set your predefined value instead of null
$x = (!empty($a)) ? $a : (!empty($b)) ? $b : (!empty($c)) ? $c : (!empty($d)) ? $d : null;
If you need a function then you can simply achieve it as
$a = '';
$b = 'hello';
$c = '';
$d = 'post';
function getX(){
$args = func_get_args();
$counter = 1;
return current(array_filter($args,function($c) use (&$counter){ if(!empty($c) && $counter++ == 1){return $c;} }));
}
$x = getX($a, $b, $c, $d);
echo $x;
Update
I've managed to create a function for you that achieves exactly what you desire, allowing infinite arguements being supplied and fetching as you desire:
function _vars() {
$args = func_get_args();
// loop through until we find one that isn't empty
foreach($args as &$item) {
// if empty
if(empty($item)) {
// remove the item from the array
unset($item);
} else {
// return the first found item that exists
return $item;
}
}
// return false if nothing found
return false;
}
To understand the function above, simply read the comments above.
Usage:
$a = _vars($_POST['x'], $_SESSION['x']);
And here is your:
Example
It is a very simply ternary operation. You simply need to check the post first and then check the session after:
$a = (isset($_POST['x']) && !empty($_POST['x']) ?
$_POST['x']
:
(isset($_SESSION['x']) && !empty($_SESSION['x']) ? $_SESSION['x'] : null)
);
PHP 7 solution:
The ?? operator.
$x = expr1 ?? expr2
The value of $x is expr1 if expr1 exists, and is not NULL.
If expr1 does not exist, or is NULL, the value of $x is expr2.
https://www.php.net/manual/en/migration70.new-features.php#migration70.new-features.null-coalesce-op
It would be simple -
$x = (!empty($_POST['x']) ? $_POST['x'] :
(!empty($_SESSION['x']) ? $_SESSION['x'] : null)
);
<?php
$my_array = array("hello","world","howareu");
$c = count($my_array);
for($i=0;$i<=$c;$i++){
$v = '$var'.$i;
$splited = list($v) = $my_array;
}
?>
input:
$my_array
But expected output:
if I echo $var0, $var1, $var2;
hello, world, howareu
How to create dynamic PHP variables based upon the array count and then convert them into a list as a string?
You do not need list for that. $$ will suit you perfectly.
$my_array = array("hello", "world", "howareu");
foreach ($my_array as $key => $val)
{
$a = 'var'.$key;
$$a = $val;
}
echo $var0,", ", $var1,", " $var2;
Take a look here - Variable variables
Added:
or if you need count and for
for ($i = 0; $i < count($my_array); $i++)
{
$a = 'var'.$i;
$$a = $my_array[$i];
}
echo $var0,", ", $var1,", " $var2;
Of course, this line echo $var0,", ", $var1,", " $var2; sucks and looks like crap :) But in order to receive EXACTLY what you want, you need to modify variables, output like I've wrote, or use some function like implode with grue ', '.
Updated:
But if you need just that output, why not to use simple implode(', ', $my_array) :)
it's a matter of the data you need to process...if it's pretty static, you don't need the second foreach() for example, since you compare the keys anyways...
foreach($datavalueas $resultdatakey=>$resultdatavalue){
if($resultdatakey== 'A'){
//stuff for a
}
if($resultdatakey== 'B'){
//stuff for b
}
}
would become
if(isset($datavalueas['A'])){
//stuff for a
}
if(isset($datavalueas['B'])){
//stuff for b
}
since the foreach uses copies of the array, which are pretty bad for the performance...
Assuming i got your question right, you could use something like:
$array = array( 'x', 'y', 'z' );
foreach ($array as $name )
$$name = rand(1,100);
var_dump($x);
the $$ is key here, the first $ implies the variable as the second $ is used as the identifier for the variable. In this case the value being iterated over in the array. Giving us 3 variables: $x, $y, $z.
-- edit:
the correct code, besides using extract():
<?php
$my_array = array("hello","world","howareu");
$c = count($my_array);
for($i=0;$i < $c;$i++){
$v = 'var'.$i;
$$v = $my_array[$i];
}
echo "$var0, $var1, $var2";
?>
You can create dynamic variables via variables variable as Mr.kovpack have stated here. In below code you can access the variables from 0 to $c-1(count of array) as per your comment to Mr.kovpack.
$my_array = array("hello","world","howareu");
$c = count($my_array);
for($i=0;$i<=$c-1;$i++){
${'var'.$i} = $my_array[$i]; //Dynamic variable creation
// $splited = list($v) = $my_array;
}
echo $var0.$var1.$var2;
or you could use like below:
$my_array = array("hello","world","howareu");
$c = count($my_array);
for($i=0;$i<=$c-1;$i++){
$a='var'.$i;
$$a = $my_array[$i];
}
echo $var0."-".$var1."-".$var2;
You can read more on it here
I read php document and I saw this:
class foo{
var $bar = 'I am a bar';
}
$foo = new foo();
$identity = 'bar';
echo "{$foo->$identity}";
And I saw somebody wrote like this:
if (!isset($ns->job_{$this->id})){
//do something
}
But when I tried with this code, It didn't work:
$id1 = 10;
$no = 1;
echo ${id.$no};
Can you guys tell me why it didn't work and when I can use braces with variable correctly?
Live example
Brackets can be used on object types, for instance, to simulate a array index. Supposing that $arr is an array type and $obj an object, we have:
$arr['index'] ===
$obj->{'index'}
You can make it more fun, for instance:
$arr["index{$id}"] ===
$obj->{"index{$id}"}
Even more:
$arr[count($list)] ===
$obj->{count($list)}
Edit: Your problem --
variable of variable
// Your problem
$id1 = 10;
$no = 1;
$full = "id{$no}";
var_dump($$full); // yeap! $$ instead of $
What are you expecting?
$id = 10;
$no = 1;
echo "${id}.${no}"; // prints "10.1"