I have this question, and i can't find any radical answer...
So, is there any possibility to set two variable in one variable
if ($post) {
$'item_name'. $x .' = $_POST['item_name'. $x .''];
}
if x = 1 then,
$item_name1 = $_POST['item_name1'];
that's the bahivor I want to implement, a way to wright the first part of the post.
the main issue item_namex (x) could be 1, 2, 3, 4 ext
You are looking for variable variables in PHP:
$x = 7;
$var = 'item_name' . $x;
$$var = $_POST['item_name'. $x];
and then you get $item_name7 with value you want. Also trailing concatenation of .'' in your right side of assignment is useless
foreach($_POST as $key=>$value){
$$key=$value;
}
For every $key variable will be created and $value would be assigned to it
Related
I have a task (or more like a challenge) found on Code-Signal (a site where do you can do some programming-related tasks. This special task was asked by google in an interview:
If you want to try it for yourself: Code-Fight.
After solving an issue, you are allowed to see other solutions.
My task was "find the first dupe in an array". I managed to do this (i'll show the way), but I'm not happy with my result. After investigating the top-solutions, I was confused, since I don't understand whats going on there.
This was (a) given example input array
$a = [2, 1, 3, 5, 3, 2]
My solution:
function firstDuplicate($a) {
$onlyDupesArray= array();
$countedValues = array_count_values($a);
// remove all entries which are only once in the array
foreach($a as $k => $v) {
if($countedValues[$v] > 1) {
$onlyDupesArray[$v] = $v;
}
}
// get rid of dupes
$uniqueDupesArray = array_unique($onlyDupesArray);
$firstEncounter = PHP_INT_MAX;
foreach($uniqueDupesArray as $k => $v) {
if(array_keys($a, $v)[1] < $firstEncounter) {
$firstEncounter = array_keys($a, $v)[1];
}
}
if(is_null($a[$firstEncounter])) {
return -1;
} else {
return $a[$firstEncounter];
}
}
It works in every test-case and I solved the challenge. However, the top-solution was this:
function firstDuplicate($a) {
foreach ($a as $v)
if ($$v++) return $v;
return -1;
}
I know what a variable variable is, but haven't seen this in the wild-life yet until now.
What does the references variable do here? How is this returning a dupe? Does it somehow compare if there is already a value for a key with this typing? Does $$v++ reference a key in an array?
Needlessly to say, I like this approach muche more. It seems way more efficient and better to maintain.
Is this "common practice"?
It is creating numbered variables. $2, $1, $3 etc.
$v in the foreach contains the current number, 2. By doing $test = 2; echo $$test we can see what is in $2 right now. It is normally empty. Now, by doing $$v++, it will return the current value (empty, or actually, variable does not exist), but ++ will put '1' in it. The whole statement itself will return 0, since ++ is not in front of the variable.
Consider this code:
$arr = [2, 1, 3, 5, 3, 2];
foreach($arr as $v)
{
$$v++;
}
$test = 3;
echo $$test;
It will show that the value of $3 equals 2, because we did 2 times ++ on $3.
The only reason this is weird is that normally you can't use variables starting with numbers. Maybe this makes it clearer?:
$arr = [2, 1, 3, 5, 3, 2];
foreach($arr as $v)
{
$v='a'.$v;
$$v++;
}
echo "a3 = $a3\n"; // 2
echo "a2 = $a2\n"; // 2
echo "a1 = $a1\n"; // 1
echo "a5 = $a5\n"; // 1
To answer the question "Is this "common practice"?". No, I would personally not use variable variables, as this can in some cases been considered as a security problem. I personally like the following solution better, which is the same, but uses an array, and does not throw notices:
function firstDuplicate($a) {
$arr = [];
foreach ($a as $v)
if (in_array($v, $arr))
return $v;
else
$arr[] = $v;
return -1;
}
The variable variables solution is a creative one, though!
By specifying your variable with an additional $ (variables variable) PHP creates a "hidden/fake array".
While running each index gets filled with a "0":
After the first run you got something like
$array[2] = 0;
After the next run the index 1 gets filled:
$array[1] = 0;
$array[2] = 0;
Since a "0" is treated as false, your condition becomes valid after the first duplicate (3):
$array[1] = 0;
$array[2] = 0;
$array[3] = 1; // <-- TRUE
$array[5] = 0;
I'm writing a script and it seems like a bit of a ballache so I came on SO to ask for a little help making my script more dynamic so I create a better version of what I'm doing. I've read into variable variables but I'm still stuck on how I'd use them.
I'll obviously shorten this down but my current script is:
$a0 = $tags['items'][0]['snippet']['tags'];
$a1 = $tags['items'][1]['snippet']['tags'];
$a2 = $tags['items'][2]['snippet']['tags'];
if (!is_array($a0)) { $a0 = array(); }
if (!is_array($a1)) { $a1 = array(); }
if (!is_array($a2)) { $a2 = array(); }
$a0 = array_map('strtolower', $a0);
$a1 = array_map('strtolower', $a1);
$a2 = array_map('strtolower', $a2);
array_count_values(array_merge($a0,$a1,$a2));
I'm looking for a way to dynamically create the variables (For example using an index in a while loop rather than creating these variables uniquely. This obviously is fine on a small scale, but i've currently done 50 of these for each and it's causing serious time problems. Any help is much appreciated
Treat the whole $tags variable as an array and you can do this, similar to the strtolower array_map you have already:
$tagItems = [];
foreach($tags['items'] as $item) {
if (!$item['snippet']['tags'] || !is_array($item['snippet']['tags'])) {
continue;
}
foreach($item['snippet']['tags'] as $tag) {
$tag = strtolower($tag);
if (!isset($tagItems[$tag])) {
$tagItems[$tag] = 0;
}
$tagItems[$tag]++;
}
}
As #FranzGleichmann says, try not to use variable variables, which are a smell and potential security risk, but instead rethink how you want to approach the problem.
You should be able to produce the same output that you get from array_count_values with a nested foreach loop.
foreach ($tags['items'] as $x) { // loop over the list of items
foreach ($x['snippet']['tags'] as $tag) { // loop over the tags from each item
$tag = strtolower($tag);
if (!isset($counts[$tag])) $counts[$tag] = 0;
$counts[$tag]++; // increment the tag count
}
}
No need to create 100 variables. That would cause a headache. Instead, use a simple loop function.
$b = array();
for ($n=1; $n<=100; $n++) {
$a = $tags['items']["$n"]['snippet']['tags'];
if (!is_array($a)) { $a = array(); }
$a = array_map('strtolower', $a);
array_count_values(array_merge($b,$a));
}
I hope it works! Have a nice coding
I would write this in a comment but i will a long one,
Variable Variable, is simply the value of the original var assigned as a var name, which means:
$my_1st_var = 'im_1st';
//use $$
$$my_1st_var = 'im_2nd'; //that is the same of $im_1st='im_2nd';
//results
echo $my_1st_var; // >>> im_1st
echo $im_1st; // >>> im_2nd
that means i created a new var and called it the value of the 1st var which is im_1st and that makes the variable name is $im_1st
also you can set multiple values as a var name:
$var0 = 'a';
$var1 = 'b';
$var2 = 'c';
$var3 = '3';
//we can do this
${$var0.$var1} = 'new var 1'; //same as: $ab = 'new var 1';
${$var1.$var2.$var3} = 'im the newest'; //same as: $bc3 = 'im the newest';
//set a var value + text
${$var0.'4'.$var1} = 'new?'; //same as: $a4b = 'new?';
also $GOLBALS[]; is some kind of $$
hope it helps you understanding what is hard for you about $$ ;)
Alright so dynamically creating variables is easy is a script language like PHP.
You could make $a an array, and instead of $a0, $a1, ... use $a[$i] where $i goes from 0 to 50 or more.
Or you could use this nice funky syntax: ${'a'.$i}. For example:
$i = 0;
${'a'.$i} = 'foobar';
echo $a0; // will output foobar
However you shouldn't do any of this.
What you should do is think about what you are trying to achieve and come up with a different algorithm that doesn't require dynamically named variables.
In this case, something like this looks like it would do the job:
$result = [];
foreach ( $tags['items'] as $item ) {
if ( is_array($item['snippet']['tags']) ) {
$result = array_merge($result, array_map('strtolower',$item));
}
}
array_count_values($result);
This is obviously not tested and from the top of my head, but I hope you get the idea. (EDIT: or check the other answers with similarly rewritten algorithms)
$marks . $count = mysqli_real_escape_string($con, $_POST['marks$count']);
I want to use $count (variable) in ($con . $_POST[])
But as I tried it gave me error. I am very new for php coding.
You can't concatenate before assignment. The proper ways to use string variable concatenation:
$marks .= $count; //option 1
$newVar = $marks.$count; //option 2
$marks = $marks.$count; //option 3
$newVar = "$marks$count"; //option 4
The way you are attempting, there is no clear variable to make the assignment to. The value on the right side of the equal is being assigned to what's on the left side of the equal sign. Two variables on the left side is ambiguous.
You could do something like:
for($count=0;!empty($_POST['marks'][$count]);$count++){
$marks[$count] = mysqli_real_escape_string($con, $_POST['marks'][$count]);
}
At the end of the cycle, array $marks will contain all escaped values of array $_POST['marks'].
I have about 45 different values that I need to add, and to avoid having a really long line of variable + variable + variable, I'm looking for a way to add them vertically to make it easier to read.
Only thing I can think of is to load them into an array, but is there a better way?
$variable+
$variable+
$variable+
$variable+
Load them all into an array and then use array_sum
This is pretty dirty, but if you have a common variable name pattern, like the last 6-10 characters as you say. Then you could do this:
$postfixPatterns = array("xxxxxx", "yyyyyy");
$definedVars = get_defined_vars();
$sums = array_combine($postfixPatterns, array_fill(0, count($postfixPatterns), 0));
foreach ($definedVars as $cVarName => $cVar) {
foreach ($postfixPatterns as $cPattern) {
if (preg_match("/" . preg_quote($cPattern, "/") . "$/", $cVarName)) {
$sums[$cVarName] += $cVar;
}
}
}
// var_dump($sums); --> array('xxxxxx' => sum of xxxxxx,
// 'yyyyyy' => sum of yyyyyy);
Of course it would be better to refactor the code to store the values in an array in the first place!
You can also use this syntax :
$sum = $var1;
$sum += $var2;
$sum += $var3;
...
I know this is not the proper way to do this, however I am trying to put a quick fix on a form that was done by another developer. Basically I want to add an incremental number to a variable inside a while statement:
$count = 1;
while ($r = mysql_fetch_array($query)) {
$variable . $count = $r['somefield'];
$count++
}
So that makes the variables:
$variable1
$variable2
$variable3
....etc
$varname = 'variable' . $count;
$$varname = $r['somefield'];
http://www.php.net/manual/en/language.variables.variable.php
You'd be better off with an array...
$variable[] = $r['somefield'];
You can use variable variables, however it is probably not a good idea, especially for a trivial case like this one.