My goal is to have a loop where variable names are created. Such as:
$variable1
$variable2
$variable3
and assigned values within the loop. For instance, a for loop from 1 to 7 produces the variables $variable1, $variable2, $variable3, .etc, each with the value of the iterator.
There are several ways. One is via a string and a double $, but I don't like this method. A programmer could easily remove the double $ (seeing it as a typeo).
for($i = 0; $i <= 7; $i++) {
$name = "variable{$i}";
$$name = "foo";
}
The best approach is the explicit statement.
for($i = 0; $i <= 7; $i++) {
${"variable$i"} = "foo";
}
With the explicit inline string there is no doubt about the intent of what you're doing. Another PHP programmer will not alter the code by mistake.
You should use an array for this:
for($i = 1; $i <= 7; $i++) {
$variable[$i] = $i;
}
Edit: to clarify, you should use an array because there's no code (to my knowledge) which will accept $variable1 but not $variable[1]. Dynamically generating variable names is all kinds of wrong.
Just to expand on what others have said about why this is a technique best avoided: variable names exist solely for use by the programmer; they have no relationships or properties according to the language's runtime. As such, a collection of related variables should be put into a variable representing some appropriate container - in the case of PHP, its incredibly flexible "array" type.
Whenever the issue of dynamically named variables is raised, it is usually because somebody thinks it is a solution to a particular problem, but it generally leads to more problems than it solves - for instance, once part of a program starts dynamically naming variables, everywhere that wants to use those variables now also has to dynamically name them; finding out which items are actually set becomes unnecessarily complex, and so on.
There are a very few contexts where variable-variables are useful, for certain kinds of debugging and meta-programming, for example, but like goto, their presence in the language should not mean you don't try every other possible solution first.
999 times out of 1000, though, if you find yourself wondering how to dynamically create variable names, you should reframe the question: what are you actually trying to achieve, and what is the best solution to that problem. If some existing / 3rd-party code has been built using this pattern (and presumably also global variables), it may be best to patch or wrap it rather than propogating the mis-design into your own code. (Admittedly, a wrapper will still need to know how to declare the dynamic variables.)
If you had an associative array i'ld prefer using the extract() method. Check it out here
for example
<?php
/* Suppose that $var_array is an array*/
$var_array = array("color" => "blue",
"size" => "medium",
"shape" => "sphere");
extract($var_array, EXTR_PREFIX_SAME, "wddx");
echo "$color, $size, $shape";
?>
the above code would output,
blue, large, sphere, medium
In case any one wants to do this through an object:
<?php
$x = 1;
while($x <= 4){
echo $q->{"a$x"};
$x++;
?>
Thats no possible since variable cannot be create in run time
Related
I've been looking all over, but I can't find a specific case on this. I'm writing a plugin for a open-source software program, and am using it's $form class and functions to render my forms without needing to manually insert in HTML.
I'm trying to make a Minimum Age (#) and Maximum Age (#) selectbox fields, each ranging from 1 to 100. I know something like this can be quickly done with something like
for ($i = 1; $i <= 99; $i++)
And then apply $i to a form in your webpage. But since this is a MVC program, I am bounded (for the most part) to what classes, objects and functions are available. When making a selectbox's actual options in this program, you typically do something like:
$field->setOptions(array(
"Value"=>"Text Label",
rinse and repeat. However, since I'm trying to make a large list of numbers, I've been trying to find a way to somehow use range() or maybe array_push in place. I've tried the following thus far:
function forAge(){
for ($i = 1; $i <= 99; $i++){
$array[] = $i;
}}
$tminage->setOptions(array(
$array[]=>$array[]));
Or trying to pass the straightup "for" method and "range" method as the array's value. None of them work, either returning errors or displaying nothing on the selectbox. I'd like to know if there's any good way of working around this, or if it's a no-go because of the specific function wanting a simple array with a value and a label.
Maybe i am missing something here but there is what I would do :
$minAgeOptions = array();
for ($i = 1; $i <= 100; $i++){
$minAgeOptions[$i] = $i;
}
$tminage->setOptions($minAgeOptions);
I have multiple variables named day1Name, day2Name, day3Name, and so on. I also have exercise_11_Name, exercise_12_name, etc.
I have a lot of those, and the value I want to save in those variables depends on user input.
I don't want to have to write $variableName = $_POST['name'] for every single one because it's a lot and a terrible practice. Therefore, I want to use a for loop so my code looks cleaner.
What I am trying to accomplish is something similar to this I believe:
for(i=0, i<10; i++)
{
$day[i+1]name = $_POST['day[i+1]name'];
$exercise_1[i+1]_name = $_POST['excName1[i]'];
}
I know the way I wrote it is not going to work though.
P.S. Where I wrote [i+1] is where I just need the number, for example, $day[i+1]name should become the variable $day1name when i=0. Where I wrote [i], for example excName1[i], that's an array in which I want to retrieve the value of that specific index.
I would really appreciate some help in this.
Thanks! =]
create an array named $day_name, and name your form fields day_name_1, day_name_2 etc
then in your loop:
$day_name[$i+1] = $_POST['day_name_' . ($i + 1)]
do the same with the exercise variables.
I assume it is php, so your loop variable has to be $i, not i
The solution you are asking for is called somewhat variable variable or variable expansion and goes on like this:
for($i=0; $i<10; $i++)
{
$d=$i+1;
${"day{$d}name"} = $_POST["day{$d}name"];
${"exercise_1{$d}_name"} = $_POST["excName1{$i}"];
}
However I encourage you to look at "array" which is somehow what #Bart suggested above, which is probably a better way of organizing your data around.
i know this
$var1 = "10";
$var2 = "var1";
then
echo $$var2 gives us 10
i want to this with array
i have array
$intake_arr = array(5=>10,7=>20,8=>30,9=>40,10=>50,11=>60,12=>70);
i have some logic that will pick one array from set of array , all array will look like $intake_arr
if i do this $target_arr = "intake_arr";
then can $$target_arr[5] will yield 10? i tried but i didnt that 10 value, how can i achieve this with array
Your statement ($$target_arr[5]) is ambiguous. PHP doesn't know what you actually want to say: Do you mean: use $target_arr[5]'s value and prepend the $, to use that as a variable, or do you want to use the value of $target_arr, and get the fifth element of that array?
Obviously it's the latter, but PHP doesn't know that. In order to disambiguate your statement, you have to use curly braces:
${$target_arr}[5];
That'll yield 10. See the manual on variable variables for details
Note:
As people said in comments, and deleted answers: variable variables, like the one you're using is risky business. 9/10 it can, and indeed should be avoided. It makes your code harder to read, more error prone and, in combination with the those two major disadvantages, this is the killer: it makes your code incredibly hard to debug.
If this is just a technical exercise, consider this note a piece of friendly advice. If you've gotten this from some sort of tutorial/blog or other type of online resource: never visit that site again.
If you're actually working on a piece of code, and you've decided to tackle a specific problem using variable vars, then perhaps post your code on code-review, and let me know, I'll have a look and try to offer some constructive criticism to help you on your way, towards a better solution.
Since what you're actually trying to do is copying an array into another variable, then that's quite easy. PHP offers a variety of ways to do that:
Copy by assignment:
PHP copies arrays on assignment, by default, so that means that:
$someArray = range(1,10);//[1,2,3,4,5,6,7,8,9,10]
$foo = $someArray;
Assigns a copy of $someArray to the variable $foo:
echo $foo[0], ' === ', $someArray[0];//echoes 1 === 1
$foo[0] += 123;
echo $foo[0], ' != ', $someArray[0];//echoes 123 != 1
I can change the value of one of the array's elements without that affecting the original array, because it was copied.
There is a risk to this, as you start working with JSON encoded data, chances are that you'll end up with something like:
$obj = json_decode($string);
echo get_class($obj));//echoes stdClass, you have an object
Objects are, by default, passed and assigned by reference, which means that:
$obj = new stdClass;
$obj->some_property = 'foobar';
$foo = $obj;
$foo->some_property .= '2';
echo $obj->some_property;//echoes foobar2!
Change a property through $foo, and the $obj object will change, too. Simply because they both reference exactly the same object.
Slice the array:
A more common way for front-end developers (mainly, I think, stemming from a JS habbit) is to use array_slice, which guarantees to return a copy of the array. with the added perk that you can specify how many of the elements you'll be needing in your copy:
$someArray = range(1,100);//"large" array
$foo = array_slice($someArray, 0);//copy from index 0 to the end
$bar = array_slice($someArray, -10);//copy last 10 elements
$chunk = array_slice($someArray, 20, 4);//start at index 20, copy 4 elements
If you don't want to copy the array, but rather extract a section out of the original you can splice the array (as in split + slice):
$extract = array_splice($someArray, 0, 10);
echo count($someArray);//echoes 90
This removes the first 10 elements from the original array, and assigns them to $extract
Spend some time browsing the countless (well, about a hundred) array functions PHP offers.
${$target_arr}[5]
PHP: Variable variables
Try this one:
$intake_arr = array(5=>10,7=>20,8=>30,9=>40,10=>50,11=>60,12=>70);
$target_arr = 'intake_arr';
print ${$target_arr}[5]; //it gives 10
For a simple variable, braces are optional.But when you will use a array element, you must use braces; e.g.: ${$target_arr}[5];.As a standard, braces are used if variable interpolation is used, instead of concatenation.Generally variable interpolation is slow, but concatenation may also be slower if you have too many variables to concatenate.Take a look here for php variable variables http://php.net/manual/en/language.variables.variable.php
I'm trying to use a for-loop which loops through two arrays.
My first one looks like this:
$pos = array("Yada Yada", "Boom Boom");
And the second one looks like this:
$pos_var_names = array("yada", "boom");
My goal is to use a for-loop to automatically loop through both arrays at the same time and for example set:
$yada = "Yada Yada";
How do I do this in the most efficient way?
Sorry if I'm missing something obvious. Have been coding for a couple of hours straight and I'm feeling a bit dizzy.
Best regards!
You could use a for-loop:
for ($i = 0; $i < count($pos); $i++)
${$pos_var_names[$i]} = $pos[$i]; // variable variables
But it is more elegant like this:
extract(array_combine($pos_var_names, $pos));
This just makes an $varname => $pos array (see also the documentation for array_combine which is then extract()'ed.
But generally, it's better to just have an associative array instead of using tons of variables. It just will fill your variable scope with useless variables which might conflict with other variables you have.
I asked this question before, Here however I think I presented the problem poorly, and got quite a few replies that may have been useful to someone but did not address the actual question and so I pose the question again.
Is there a single-line native method in php that would allow me to do the following.
Please, please, I understand there are other ways to do this simple thing, but the question I present is does something exist natively in PHP that will grant me access to the array values directly without having to create a temporary array.
$rand_place = explode(",",loadFile("csvOf20000places.txt")){rand(0,1000)};
This is a syntax error, however ideally it would be great if this worked!
Currently, it seems unavoidable that one must create a temporary array, ie
The following is what I want to avoid:
$temporary_places_array = explode(",",loadFile("csvOf20000places.txt"));
$rand_place = $temporary_places_array[rand(0,1000)];
Also, i must note that my actual intentions are not to parse strings, or pull randomly from an array. I simply want access into the string without a temporary variable. This is just an example which i hope is easy to understand. There are many times service calls or things you do not have control over returns an array (such as the explode() function) and you just want access into it without having to create a temporary variable.
NATIVELY NATIVELY NATIVELY, i know i can create a function that does it.
No, there is no way to do that natively.
You can, however:
1.- Store the unavoidable array instead of the string. Given PHP's limitation this is what makes most sense in my opinion.
Also, don't forget you can unset()
2.- Use strpos() and friends to parse the string into what you need, as shown in other answers I won't paste here.
3.- Create a function.
There is no native PHP method of doing this.
You could make a function like this:
function array_value($array, $key) {
return $array[$key];
}
And then use it like this:
$places = "alabama,alaska,arizona .... zimbabway";
$random_place = array_value(explode(",", $places), rand(0, 1000));
I know it's poor form to answer a question with a question, but why are you concerned about this? Is it a nitpick, or an optimization question? The Zend engine will optimize this away.
However, I'd point out you don't have to create a temporary variable necessarily:
$rand_place = explode(",",loadFile("csvOf20000places.txt"));
$rand_place = $rand_place[rand(0,1000)];
Because of type mutability, you could reuse the variable. Of course, you're still not skipping a step.
list($rand_place) = array_slice(explode(',', loadFile("csvOf20000places.txt")), array_rand(explode(',', loadFile("csvOf20000places.txt"))), 1);
EDIT: Ok, you're right. The question is very hard to understand but, I think this is it. The code above will pull random items from the csv file but, to just pull whatever you want out, use this:
list($rand_place) = array_slice(explode(',', loadFile("csvOf20000places.txt")), {YOUR_NUMBER}, 1);
Replace the holder with the numeric key of the value you want to pull out.
If it's memory concerns, there are other ways of going about this that don't split out into an array. But no, there is nothing builtin to handle this sort of situation.
As an alternative, you might try:
$pos = 0;
$num = 0;
while(($pos = strpos($places, ',', $pos+1)) !== false) {$num++;}
$which = rand(0, $num);
$num = 0;
while($num <= $which) {$pos = strpos($places, ',', $pos+1);}
$random_place = substr($places, $pos, strpos($places, ',', $pos+1));
I havn't tested this, so there may be a few off-by-one issues in it, but you get the idea. This could be made shorter (and quicker) by cacheing the positions that you work out in the first loop, but this brings you back to the memory issues.
You can do this:
<?php
function foo() {
return new ArrayObject(explode(",", "zero,one,two"));
}
echo foo()->offsetGet(1); // "one"
?>
Sadly you can't do this:
echo (new ArrayObject(explode(",", "zero,one,two")))->offsetGet(2);
I spent a great deal of last year researching advanced CSV parsing for PHP and I admit it would be nice to randomly seek at will on a file. One of my semi-deadend's was to scan through a known file and make an index of the position of all known \n's that were not at the beginning of the line.
//Grab and load our index
$index = unserialize(file_get_contents('somefile.ext.ind'));
//What it looks like
$index = array( 0 => 83, 1 => 162, 2 => 178, ....);
$fHandle = fopen("somefile.ext",'RB');
$randPos = rand(0, count($index));
fseek($fHandle, $index[$randPos]);
$line = explode(",", fgets($fHandle));
Tha's the only way I could see it being done anywhere close to what you need. As for creating the index, that's rudimentary stuff.
$fHandle = fopen('somefile.ext','rb');
$index = array();
for($i = 0; false !== ($char = fgetc($fHandle)); $i++){
if($char === "\n") $index[] = $i;
}